Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add: add math.pow #836

Closed
wants to merge 16 commits into from
Closed
28 changes: 0 additions & 28 deletions src/Neo.Compiler.CSharp/MethodConvert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4513,44 +4513,16 @@ private bool TryProcessSystemMethods(SemanticModel model, IMethodSymbol symbol,
PrepareArgumentsForMethod(model, symbol, arguments);
Call(NativeContract.StdLib.Hash, "atoi", 1, true);
return true;
case "System.Math.Abs(sbyte)":
case "System.Math.Abs(short)":
case "System.Math.Abs(int)":
case "System.Math.Abs(long)":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove this compatibility?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to avoid confusion, use Neo.Math everywhere instead of System.Math. Otherwise you will have two Math system.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to use native C#. This may why developers can't program in C# (I guess). No internet search will tell them to use Neo.math, unless the NC error says to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @cschuchardt88

Copy link
Contributor Author

@Jim8y Jim8y Dec 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't, many of them use double, i think you know what the issue is @shargon.
And I do not think using C# native is a good idea, this is neo C#, instead of dotnet C#, using dotnet C# causes confusion as people do not know what can be done and what can not.

We use C# syntax, its good, but using C# native framwork is another story as it has double, float, decimal and tons of other types and methods that can not be supported by neo, are we going to tell them one by one this is not supported and that is not supported? Though the analyzer can do that, but having our own to strickly and accurately tell them would be better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where do you know what method is supported by neo @cschuchardt88? only at compile time right? how does it feel? every time you use something, you know if it works only if you compile it......

Copy link
Member

@cschuchardt88 cschuchardt88 Dec 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understandable, Maybe we should phase out all native dotnet APIs and only have Neo types & functions. For example, Neo.Math.Abs, Neo.String and etc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly what i have in mind.

case "System.Numerics.BigInteger.Abs(System.Numerics.BigInteger)":
if (arguments is not null)
PrepareArgumentsForMethod(model, symbol, arguments);
AddInstruction(OpCode.ABS);
return true;
case "System.Math.Sign(sbyte)":
case "System.Math.Sign(short)":
case "System.Math.Sign(int)":
case "System.Math.Sign(long)":
if (arguments is not null)
PrepareArgumentsForMethod(model, symbol, arguments);
AddInstruction(OpCode.SIGN);
return true;
case "System.Math.Max(byte, byte)":
case "System.Math.Max(sbyte, sbyte)":
case "System.Math.Max(short, short)":
case "System.Math.Max(ushort, ushort)":
case "System.Math.Max(int, int)":
case "System.Math.Max(uint, uint)":
case "System.Math.Max(long, long)":
case "System.Math.Max(ulong, ulong)":
case "System.Numerics.BigInteger.Max(System.Numerics.BigInteger, System.Numerics.BigInteger)":
if (arguments is not null)
PrepareArgumentsForMethod(model, symbol, arguments);
AddInstruction(OpCode.MAX);
return true;
case "System.Math.Min(byte, byte)":
case "System.Math.Min(sbyte, sbyte)":
case "System.Math.Min(short, short)":
case "System.Math.Min(ushort, ushort)":
case "System.Math.Min(int, int)":
case "System.Math.Min(uint, uint)":
case "System.Math.Min(long, long)":
case "System.Math.Min(ulong, ulong)":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this part should be in another PR, @Jim8y .

It is a good point to discuss

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, will move it to another pr.

case "System.Numerics.BigInteger.Min(System.Numerics.BigInteger, System.Numerics.BigInteger)":
if (arguments is not null)
PrepareArgumentsForMethod(model, symbol, arguments);
Expand Down
121 changes: 121 additions & 0 deletions src/Neo.SmartContract.Framework/Math.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Copyright (C) 2015-2023 The Neo Project.
//
// The Neo.SmartContract.Framework is free software distributed under the MIT
// software license, see the accompanying file LICENSE in the main directory
// of the project or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.SmartContract.Framework.Attributes;
using System.Numerics;
using System.Runtime.InteropServices;

namespace Neo.SmartContract.Framework
{
public class Math
{
[CallingConvention(CallingConvention.StdCall)]
[OpCode(OpCode.POW)]
public static extern BigInteger Pow(BigInteger x, BigInteger y);
[CallingConvention(CallingConvention.StdCall)]
[OpCode(OpCode.POW)]
public static extern BigInteger Pow(long x, long y);
[CallingConvention(CallingConvention.StdCall)]
[OpCode(OpCode.POW)]
public static extern BigInteger Pow(int x, int y);
[CallingConvention(CallingConvention.StdCall)]
[OpCode(OpCode.POW)]
public static extern BigInteger Pow(ulong x, ulong y);
[CallingConvention(CallingConvention.StdCall)]
[OpCode(OpCode.POW)]
public static extern BigInteger Pow(uint x, uint y);
[CallingConvention(CallingConvention.StdCall)]
[OpCode(OpCode.POW)]
public static extern BigInteger Pow(short x, short y);
[CallingConvention(CallingConvention.StdCall)]
[OpCode(OpCode.POW)]
public static extern BigInteger Pow(ushort x, ushort y);
[CallingConvention(CallingConvention.StdCall)]
[OpCode(OpCode.POW)]
public static extern BigInteger Pow(byte x, byte y);
shargon marked this conversation as resolved.
Show resolved Hide resolved
[CallingConvention(CallingConvention.StdCall)]
[OpCode(OpCode.POW)]
public static extern BigInteger Pow(sbyte x, sbyte y);

[OpCode(OpCode.ABS)]
public static extern sbyte Abs(sbyte x);
[OpCode(OpCode.ABS)]
public static extern short Abs(short x);
[OpCode(OpCode.ABS)]
public static extern int Abs(int x);
[OpCode(OpCode.ABS)]
public static extern long Abs(long x);

[OpCode(OpCode.SIGN)]
public static extern sbyte Sign(sbyte x);
[OpCode(OpCode.SIGN)]
public static extern short Sign(short x);
[OpCode(OpCode.SIGN)]
public static extern int Sign(int x);
[OpCode(OpCode.SIGN)]
public static extern long Sign(long x);

[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MAX)]
public static extern byte Max(byte x, byte y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MAX)]
public static extern sbyte Max(sbyte x, sbyte y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MAX)]
public static extern short Max(short x, short y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MAX)]
public static extern ushort Max(ushort x, ushort y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MAX)]
public static extern int Max(int x, int y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MAX)]
public static extern uint Max(uint x, uint y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MAX)]
public static extern long Max(long x, long y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MAX)]
public static extern ulong Max(ulong x, ulong y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MAX)]
public static extern BigInteger Max(BigInteger x, BigInteger y);

[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MIN)]
public static extern byte Min(byte x, byte y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MIN)]
public static extern sbyte Min(sbyte x, sbyte y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MIN)]
public static extern short Min(short x, short y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MIN)]
public static extern ushort Min(ushort x, ushort y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MIN)]
public static extern int Min(int x, int y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MIN)]
public static extern uint Min(uint x, uint y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MIN)]
public static extern long Min(long x, long y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MIN)]
public static extern ulong Min(ulong x, ulong y);
[CallingConvention(CallingConvention.Cdecl)]
[OpCode(OpCode.MIN)]
public static extern BigInteger Min(BigInteger x, BigInteger y);
}
}
156 changes: 155 additions & 1 deletion tests/Neo.Compiler.CSharp.UnitTests/TestClasses/Contract_Math.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Numerics;
using Neo.SmartContract.Framework;

namespace Neo.Compiler.CSharp.UnitTests.TestClasses
{
Expand All @@ -23,5 +24,158 @@ public static int abs(int a)
{
return Math.Abs(a);
}


// Test for BigInteger Pow(BigInteger x, BigInteger y)
public static BigInteger TestPow(BigInteger a, BigInteger b)
{
return Math.Pow(a, b);
}

// Test for BigInteger Pow(long x, long y)
public static BigInteger TestPow1(long a, long b)
{
return Math.Pow(a, b);
}

// Test for BigInteger Pow(int x, int y)
public static BigInteger TestPow2(int a, int b)
{
return Math.Pow(a, b);
}

// Test for Abs methods
public static sbyte TestAbs(sbyte x)
{
return Math.Abs(x);
}

public static short TestAbs2(short x)
{
return Math.Abs(x);
}

public static int TestAbs3(int x)
{
return Math.Abs(x);
}

public static long TestAbs4(long x)
{
return Math.Abs(x);
}

// Test for Sign methods
public static sbyte TestSign(sbyte x)
{
return Math.Sign(x);
}

public static short TestSign1(short x)
{
return Math.Sign(x);
}

public static int TestSign2(int x)
{
return Math.Sign(x);
}

public static long TestSign3(long x)
{
return Math.Sign(x);
}

// Test for Max methods
public static byte TestMax(byte x, byte y)
{
return Math.Max(x, y);
}

public static sbyte TestMax1(sbyte x, sbyte y)
{
return Math.Max(x, y);
}

public static short TestMax2(short x, short y)
{
return Math.Max(x, y);
}

public static ushort TestMax3(ushort x, ushort y)
{
return Math.Max(x, y);
}

public static int TestMax4(int x, int y)
{
return Math.Max(x, y);
}

public static uint TestMax5(uint x, uint y)
{
return Math.Max(x, y);
}

public static long TestMax6(long x, long y)
{
return Math.Max(x, y);
}

public static ulong TestMax7(ulong x, ulong y)
{
return Math.Max(x, y);
}

public static BigInteger TestMax8(BigInteger x, BigInteger y)
{
return Math.Max(x, y);
}

// Test for Min methods
public static byte TestMin(byte x, byte y)
{
return Math.Min(x, y);
}

public static sbyte TestMin1(sbyte x, sbyte y)
{
return Math.Min(x, y);
}

public static short TestMin2(short x, short y)
{
return Math.Min(x, y);
}

public static ushort TestMin3(ushort x, ushort y)
{
return Math.Min(x, y);
}

public static int TestMin4(int x, int y)
{
return Math.Min(x, y);
}

public static uint TestMin5(uint x, uint y)
{
return Math.Min(x, y);
}

public static long TestMin6(long x, long y)
{
return Math.Min(x, y);
}

public static ulong TestMin7(ulong x, ulong y)
{
return Math.Min(x, y);
}

public static BigInteger TestMin8(BigInteger x, BigInteger y)
{
return Math.Min(x, y);
}
}
}
Loading