public void TestValueEncoding() { foreach (var tv in tvs) { var sn = new ScriptNum(tv.v64); Assert.Equal(tv.v64, sn.GetValue()); Assert.Equal(tv.v32, sn.GetInt()); Assert.Equal(tv.hex, sn.GetHex()); sn = new ScriptNum(tv.hex); Assert.Equal(tv.v64, sn.GetValue()); Assert.Equal(tv.v32, sn.GetInt()); Assert.Equal(tv.hex, sn.GetHex()); } }
/// <summary> /// Returns this value as a number resized to a specified size. /// If size is null, attempts to encode as the minimum size. /// The current value's most significant bit is assumed to be the sign bit. /// There can be any amount of zero byte padding between the sign bit and /// the first set numeric value bit. /// A single "padding" zero byte is required if the x80 bit is set on the byte following it (to keep the value positive). /// Effectively adjusts the position of the sign bit after adjusting zero byte padding. /// </summary> /// <param name="size">Target size or null to minimally encode.</param> /// <returns>Tuple of (bin, ok) where: /// bin may be original value if size matches, otherwise new storage is allocated. None on failure. /// ok is true on success. False if can't fit in size. /// </returns> public (VarType bin, bool ok) NumResize(uint?size = null) { var data = ToSpan(); var(tooLong, isNeg, extraBytes) = ScriptNum.EvaluateAsNum(data); if (size == null && tooLong) { goto fail; } var length = (uint)data.Length - extraBytes; size ??= length; if (length > size) { goto fail; } if (Length == size) { return(this, true); } var bytes = new byte[(int)size]; if (size > 0) { data.Slice(0, (int)length).CopyTo(bytes.AsSpan()); // Remove the sign bit, add padding 0x00 bytes, restore the sign bit. // If number is positive, they start cleared, nothing to do. if (isNeg) { // Move the set sign bit. // Only clear the old bit in new array if we copied the byte. if (extraBytes == 0) { bytes[length - 1] &= 0x7f; } // Only set the new bit in the new array if the value isn't zero. // Always convert negative zero to positive zero. if (extraBytes < data.Length) { bytes[^ 1] |= 0x80;
public override int GetHashCode() { return(base.GetHashCode() ^ Set.GetHashCode() ^ ObjectNum.GetHashCode() ^ ScriptNum.GetHashCode() ^ BrickNum.GetHashCode() ^ VariableNum.GetHashCode()); }