Skip to content

Commit

Permalink
fix BigInteger IsPowerOfTwo (#1172)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hecate2 authored Sep 19, 2024
1 parent a0be8f3 commit 9bda2cf
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -544,25 +544,6 @@ private static void HandleBigIntegerCreatedChecked(MethodConvert methodConvert,
methodConvert.PrepareArgumentsForMethod(model, symbol, arguments);
}

private static void HandleBigIntegerIsPowerOfTwo(MethodConvert methodConvert, SemanticModel model, IMethodSymbol symbol, ExpressionSyntax? instanceExpression, IReadOnlyList<SyntaxNode>? arguments)
{
if (arguments is not null)
methodConvert.PrepareArgumentsForMethod(model, symbol, arguments);

JumpTarget endTarget = new();
methodConvert.AddInstruction(OpCode.DUP); // a a
methodConvert.AddInstruction(OpCode.PUSH0); // a a 0
methodConvert.Jump(OpCode.JMPLE, endTarget); // a
methodConvert.AddInstruction(OpCode.DUP); // a a
methodConvert.AddInstruction(OpCode.DEC); // a a-1
methodConvert.AddInstruction(OpCode.AND); // a&(a-1)
methodConvert.AddInstruction(OpCode.PUSH0); // a&(a-1) 0
methodConvert.Jump(OpCode.JMPEQ, endTarget); // a&(a-1)
methodConvert.AddInstruction(OpCode.PUSH0); // 0
methodConvert.Jump(OpCode.JMP, endTarget); // 0
endTarget.Instruction = methodConvert.AddInstruction(OpCode.NOP); // NOP
}

private static void HandleBigIntegerCreateSaturating(MethodConvert methodConvert, SemanticModel model, IMethodSymbol symbol, ExpressionSyntax? instanceExpression, IReadOnlyList<SyntaxNode>? arguments)
{
if (instanceExpression is not null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private static void RegisterBigIntegerHandlers()

// Add missing BigInteger methods
// RegisterHandler((BigInteger x, double y) => BigInteger.Log(x, y), HandleBigIntegerLogBase);
RegisterHandler((BigInteger x) => x.IsPowerOfTwo, HandleBigIntegerIsPowerOfTwo);
RegisterHandler((BigInteger x) => x.IsPowerOfTwo, HandleBigIntegerIsPow2);
// RegisterHandler((BigInteger x) => BigInteger.PopCount(x), HandleBigIntegerPopCount);
RegisterHandler((BigInteger x) => BigInteger.CreateSaturating(x), HandleBigIntegerCreateSaturating);
}
Expand Down
5 changes: 5 additions & 0 deletions tests/Neo.Compiler.CSharp.TestContracts/Contract_Integer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -528,4 +528,9 @@ public static BigInteger PopCountBigInteger(BigInteger value)
{
return BigInteger.PopCount(value);
}

public static bool IsPow2BigInteger(BigInteger value)
{
return value.IsPowerOfTwo;
}
}

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions tests/Neo.Compiler.CSharp.UnitTests/UnitTest_Integer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1424,5 +1424,12 @@ public void TestPopCountBigInteger()
Assert.ThrowsException<TestException>(() => Contract.PopCountBigInteger(BigInteger.Parse("123456789123456789")));
Assert.ThrowsException<TestException>(() => Contract.PopCountBigInteger(BigInteger.Parse("-987654321987654321")));
}

[TestMethod]
public void TestMethodBigIntgerIsPow2()
{
for (int i = -2; i <= 4; ++i)
Assert.AreEqual(new BigInteger(i).IsPowerOfTwo, Contract.IsPow2BigInteger(i));
}
}
}

0 comments on commit 9bda2cf

Please sign in to comment.