mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-27 05:52:11 +00:00
add movsx, fchs
implement neg CIL (needed for Abs()) fix floor and ceiling in range of int add sign extension to LdArg and LdLoc remove unneeded math functions, like min,max,abs
This commit is contained in:
parent
bcd92cf77c
commit
51e893eb74
8 changed files with 127 additions and 208 deletions
|
|
@ -64,6 +64,7 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="MoveSignExtend.cs" />
|
||||||
<Compile Include="Lgdt.cs" />
|
<Compile Include="Lgdt.cs" />
|
||||||
<Compile Include="Lidt.cs" />
|
<Compile Include="Lidt.cs" />
|
||||||
<Compile Include="Shrd.cs" />
|
<Compile Include="Shrd.cs" />
|
||||||
|
|
@ -75,6 +76,7 @@
|
||||||
<Compile Include="SignExtendAX.cs" />
|
<Compile Include="SignExtendAX.cs" />
|
||||||
<Compile Include="CmpXchg.cs" />
|
<Compile Include="CmpXchg.cs" />
|
||||||
<Compile Include="CpuId.cs" />
|
<Compile Include="CpuId.cs" />
|
||||||
|
<Compile Include="x87\FloatNegate.cs" />
|
||||||
<Compile Include="XchgAndAdd.cs" />
|
<Compile Include="XchgAndAdd.cs" />
|
||||||
<Compile Include="Add.cs" />
|
<Compile Include="Add.cs" />
|
||||||
<Compile Include="AddWithCarry.cs" />
|
<Compile Include="AddWithCarry.cs" />
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
namespace Cosmos.Compiler.Assembler.X86 {
|
||||||
|
[OpCode("movsx")]
|
||||||
|
public class MoveSignExtend : InstructionWithDestinationAndSourceAndSize
|
||||||
|
{
|
||||||
|
|
||||||
|
public override void WriteText(Assembler aAssembler, System.IO.TextWriter aOutput)
|
||||||
|
{
|
||||||
|
if (Size == 0)
|
||||||
|
{
|
||||||
|
Size = 32;
|
||||||
|
}
|
||||||
|
aOutput.Write(mMnemonic);
|
||||||
|
if (!DestinationEmpty)
|
||||||
|
{
|
||||||
|
aOutput.Write(" ");
|
||||||
|
aOutput.Write(this.GetDestinationAsString());
|
||||||
|
aOutput.Write(", ");
|
||||||
|
aOutput.Write(SizeToString(Size));
|
||||||
|
aOutput.Write(" ");
|
||||||
|
aOutput.Write(this.GetSourceAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
namespace Cosmos.Compiler.Assembler.X86.x87
|
||||||
|
{
|
||||||
|
[OpCode("fchs")]
|
||||||
|
public class FloatNegate : Instruction
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ using Cosmos.IL2CPU.ILOpCodes;
|
||||||
using Cosmos.IL2CPU.X86;
|
using Cosmos.IL2CPU.X86;
|
||||||
using Cosmos.Compiler.Assembler;
|
using Cosmos.Compiler.Assembler;
|
||||||
using Cosmos.Compiler.Assembler.X86;
|
using Cosmos.Compiler.Assembler.X86;
|
||||||
|
using CPUx86 = Cosmos.Compiler.Assembler.X86;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.IL
|
namespace Cosmos.IL2CPU.X86.IL
|
||||||
{
|
{
|
||||||
|
|
@ -83,7 +84,6 @@ namespace Cosmos.IL2CPU.X86.IL
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DoExecute(Assembler Assembler, MethodInfo aMethod, ushort aParam) {
|
public static void DoExecute(Assembler Assembler, MethodInfo aMethod, ushort aParam) {
|
||||||
uint xArgSize = 0u;
|
|
||||||
var xDisplacement = GetArgumentDisplacement(aMethod, aParam);
|
var xDisplacement = GetArgumentDisplacement(aMethod, aParam);
|
||||||
Type xArgType;
|
Type xArgType;
|
||||||
if (aMethod.MethodBase.IsStatic) {
|
if (aMethod.MethodBase.IsStatic) {
|
||||||
|
|
@ -101,16 +101,25 @@ namespace Cosmos.IL2CPU.X86.IL
|
||||||
}
|
}
|
||||||
new Comment("Ldarg");
|
new Comment("Ldarg");
|
||||||
new Comment("Arg idx = " + aParam);
|
new Comment("Arg idx = " + aParam);
|
||||||
xArgSize = Align(SizeOfType(xArgType), 4);
|
uint xArgRealSize = SizeOfType(xArgType);
|
||||||
|
uint xArgSize = Align(xArgRealSize, 4);
|
||||||
new Comment("Arg type = " + xArgType.ToString());
|
new Comment("Arg type = " + xArgType.ToString());
|
||||||
new Comment("Arg size = " + xArgSize);
|
new Comment("Arg real size = " + xArgRealSize + " aligned size = " + xArgSize);
|
||||||
|
if (xArgRealSize < 4)
|
||||||
|
{
|
||||||
|
new CPUx86.MoveSignExtend { DestinationReg = CPUx86.Registers.EAX, Size = (byte)(xArgRealSize * 8), SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = xDisplacement };
|
||||||
|
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for (int i = 0; i < (xArgSize / 4); i++) {
|
for (int i = 0; i < (xArgSize / 4); i++) {
|
||||||
new Push {
|
new Push {
|
||||||
DestinationReg = Registers.EBP,
|
DestinationReg = Registers.EBP,
|
||||||
DestinationIsIndirect = true,
|
DestinationIsIndirect = true,
|
||||||
DestinationDisplacement = (int)(xDisplacement - (i * 4))
|
DestinationDisplacement = xDisplacement - (i * 4)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Assembler.Stack.Push(xArgSize, xArgType);
|
Assembler.Stack.Push(xArgSize, xArgType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,16 +34,9 @@ namespace Cosmos.IL2CPU.X86.IL
|
||||||
switch (xSize)
|
switch (xSize)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
{
|
|
||||||
new CPUx86.Xor { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX };
|
|
||||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.AL, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0 - xEBPOffset };
|
|
||||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
new CPUx86.Xor { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX };
|
new CPUx86.MoveSignExtend { DestinationReg = CPUx86.Registers.EAX, Size = (byte)(xSize * 8), SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0 - xEBPOffset };
|
||||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.AX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0 - xEBPOffset };
|
|
||||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -53,13 +46,8 @@ namespace Cosmos.IL2CPU.X86.IL
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#if DOTNETCOMPATIBLE
|
|
||||||
Assembler.Stack.Push(ILOp.Align(xSize, 4), xVar.LocalType);
|
Assembler.Stack.Push(ILOp.Align(xSize, 4), xVar.LocalType);
|
||||||
#else
|
|
||||||
Assembler.Stack.Push(xSize, xVar.LocalType);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using CPUx86 = Cosmos.Compiler.Assembler.X86;
|
using CPUx86 = Cosmos.Compiler.Assembler.X86;
|
||||||
using Cosmos.Compiler.Assembler.X86;
|
|
||||||
using Label = Cosmos.Compiler.Assembler.Label;
|
using Label = Cosmos.Compiler.Assembler.Label;
|
||||||
namespace Cosmos.IL2CPU.X86.IL
|
namespace Cosmos.IL2CPU.X86.IL
|
||||||
{
|
{
|
||||||
|
|
@ -19,10 +18,10 @@ namespace Cosmos.IL2CPU.X86.IL
|
||||||
{
|
{
|
||||||
if (xStackContent.IsFloat)
|
if (xStackContent.IsFloat)
|
||||||
{
|
{
|
||||||
new CPUx86.x87.FloatLoad { DestinationReg = Registers.ESP, Size = 64, DestinationIsIndirect = true };
|
new CPUx86.x87.FloatLoad { DestinationReg = CPUx86.Registers.ESP, Size = 64, DestinationIsIndirect = true };
|
||||||
new CPUx86.Add { SourceValue = 8, DestinationReg = Registers.ESP };
|
new CPUx86.Add { SourceValue = 8, DestinationReg = CPUx86.Registers.ESP };
|
||||||
new CPUx86.x87.FloatMul { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, Size = 64 };
|
new CPUx86.x87.FloatMul { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, Size = 64 };
|
||||||
new CPUx86.x87.FloatStoreAndPop { DestinationReg = Registers.ESP, Size = 64, DestinationIsIndirect = true };
|
new CPUx86.x87.FloatStoreAndPop { DestinationReg = CPUx86.Registers.ESP, Size = 64, DestinationIsIndirect = true };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -47,7 +46,7 @@ namespace Cosmos.IL2CPU.X86.IL
|
||||||
//mov RIGHT_HIGH to eax, is useable on Full 64 multiply
|
//mov RIGHT_HIGH to eax, is useable on Full 64 multiply
|
||||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = 4 };
|
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = 4 };
|
||||||
new CPUx86.Compare { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = 12 };
|
new CPUx86.Compare { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = 12 };
|
||||||
new CPUx86.ConditionalJump { Condition = ConditionalTestEnum.Zero, DestinationLabel = Simple32Multiply };
|
new CPUx86.ConditionalJump { Condition = CPUx86.ConditionalTestEnum.Zero, DestinationLabel = Simple32Multiply };
|
||||||
// Full 64 Multiply
|
// Full 64 Multiply
|
||||||
|
|
||||||
// eax contains already RIGHT_HIGH
|
// eax contains already RIGHT_HIGH
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,42 @@ namespace Cosmos.IL2CPU.X86.IL
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Execute( MethodInfo aMethod, ILOpCode aOpCode )
|
public override void Execute( MethodInfo aMethod, ILOpCode aOpCode )
|
||||||
|
{
|
||||||
|
var xStackContent = Assembler.Stack.Peek();
|
||||||
|
if (xStackContent.Size > 4)
|
||||||
|
{
|
||||||
|
if (xStackContent.IsFloat)
|
||||||
|
{
|
||||||
|
new CPUx86.x87.FloatLoad { DestinationReg = CPUx86.Registers.ESP, Size = 64, DestinationIsIndirect = true };
|
||||||
|
new CPUx86.x87.FloatNegate { };
|
||||||
|
new CPUx86.x87.FloatStoreAndPop { DestinationReg = CPUx86.Registers.ESP, Size = 64, DestinationIsIndirect = true };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EBX }; // low
|
||||||
|
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX }; // high
|
||||||
|
new CPUx86.Neg { DestinationReg = CPUx86.Registers.EBX }; // set carry if EBX != 0
|
||||||
|
new CPUx86.AddWithCarry { DestinationReg = CPUx86.Registers.EAX, SourceValue = 0 };
|
||||||
|
new CPUx86.Neg { DestinationReg = CPUx86.Registers.EAX };
|
||||||
|
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||||
|
new CPUx86.Push { DestinationReg = CPUx86.Registers.EBX };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (xStackContent.IsFloat)
|
||||||
|
{
|
||||||
|
new CPUx86.x87.FloatLoad { DestinationReg = CPUx86.Registers.ESP, Size = 32, DestinationIsIndirect = true };
|
||||||
|
new CPUx86.x87.FloatNegate { };
|
||||||
|
new CPUx86.x87.FloatStoreAndPop { DestinationReg = CPUx86.Registers.ESP, Size = 32, DestinationIsIndirect = true };
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||||
new CPUx86.Neg { DestinationReg = CPUx86.Registers.EAX };
|
new CPUx86.Neg { DestinationReg = CPUx86.Registers.EAX };
|
||||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ namespace Cosmos.System.Plugs.System
|
||||||
public const double PI = 3.14159265358979;
|
public const double PI = 3.14159265358979;
|
||||||
public const double E = 2.71828182845905;
|
public const double E = 2.71828182845905;
|
||||||
|
|
||||||
|
// TODO Abs decimal
|
||||||
#region Abs
|
#region Abs
|
||||||
public static double Abs(double value)
|
public static double Abs(double value)
|
||||||
{
|
{
|
||||||
|
|
@ -37,6 +38,7 @@ namespace Cosmos.System.Plugs.System
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* should work from ms .net
|
||||||
public static long Abs(long value)
|
public static long Abs(long value)
|
||||||
{
|
{
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
|
|
@ -59,21 +61,11 @@ namespace Cosmos.System.Plugs.System
|
||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
// TODO Max decimal
|
||||||
#region Max
|
#region Max
|
||||||
public static byte Max(byte val1, byte val2)
|
|
||||||
{
|
|
||||||
if (val1 > val2)
|
|
||||||
{
|
|
||||||
return val1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//public static decimal Max(decimal val1, decimal val2)
|
//public static decimal Max(decimal val1, decimal val2)
|
||||||
//{
|
//{
|
||||||
|
|
@ -87,79 +79,10 @@ namespace Cosmos.System.Plugs.System
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public static double Max(double val1, double val2)
|
|
||||||
{
|
|
||||||
if (val1 > val2)
|
|
||||||
{
|
|
||||||
return val1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static short Max(short val1, short val2)
|
|
||||||
{
|
|
||||||
if (val1 > val2)
|
|
||||||
{
|
|
||||||
return val1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int Max(int val1, int val2)
|
|
||||||
{
|
|
||||||
if (val1 > val2)
|
|
||||||
{
|
|
||||||
return val1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long Max(long val1, long val2)
|
|
||||||
{
|
|
||||||
if (val1 > val2)
|
|
||||||
{
|
|
||||||
return val1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float Max(float val1, float val2)
|
|
||||||
{
|
|
||||||
if (val1 > val2)
|
|
||||||
{
|
|
||||||
return val1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
//TODO Min decimal
|
||||||
#region Min
|
#region Min
|
||||||
public static byte Min(byte val1, byte val2)
|
|
||||||
{
|
|
||||||
if (val1 < val2)
|
|
||||||
{
|
|
||||||
return val1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//public static decimal Min(decimal val1, decimal val2)
|
//public static decimal Min(decimal val1, decimal val2)
|
||||||
//{
|
//{
|
||||||
|
|
@ -173,65 +96,6 @@ namespace Cosmos.System.Plugs.System
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public static double Min(double val1, double val2)
|
|
||||||
{
|
|
||||||
if (val1 < val2)
|
|
||||||
{
|
|
||||||
return val1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static short Min(short val1, short val2)
|
|
||||||
{
|
|
||||||
if (val1 < val2)
|
|
||||||
{
|
|
||||||
return val1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int Min(int val1, int val2)
|
|
||||||
{
|
|
||||||
if (val1 < val2)
|
|
||||||
{
|
|
||||||
return val1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long Min(long val1, long val2)
|
|
||||||
{
|
|
||||||
if (val1 < val2)
|
|
||||||
{
|
|
||||||
return val1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float Min(float val1, float val2)
|
|
||||||
{
|
|
||||||
if (val1 < val2)
|
|
||||||
{
|
|
||||||
return val1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Pow
|
#region Pow
|
||||||
|
|
@ -261,7 +125,7 @@ namespace Cosmos.System.Plugs.System
|
||||||
|
|
||||||
#region Sin
|
#region Sin
|
||||||
public static double Sin(double a)
|
public static double Sin(double a)
|
||||||
{
|
{ // should be using assembler instruction
|
||||||
bool signSwitch = false;
|
bool signSwitch = false;
|
||||||
double result = 0;
|
double result = 0;
|
||||||
|
|
||||||
|
|
@ -283,8 +147,6 @@ namespace Cosmos.System.Plugs.System
|
||||||
result = (radians) - (Math.Pow(radians, 3) / Factorial(3));
|
result = (radians) - (Math.Pow(radians, 3) / Factorial(3));
|
||||||
result += (Math.Pow(radians, 5) / Factorial(5)) - (Math.Pow(radians, 7) / Factorial(7)) + (Math.Pow(radians, 9) / Factorial(9));
|
result += (Math.Pow(radians, 5) / Factorial(5)) - (Math.Pow(radians, 7) / Factorial(7)) + (Math.Pow(radians, 9) / Factorial(9));
|
||||||
|
|
||||||
//result *= -1;
|
|
||||||
|
|
||||||
/* USE WHEN Modulus Works
|
/* USE WHEN Modulus Works
|
||||||
* int sign = 0;
|
* int sign = 0;
|
||||||
for (int i = 3; i < 19; i += 2)
|
for (int i = 3; i < 19; i += 2)
|
||||||
|
|
@ -318,7 +180,7 @@ namespace Cosmos.System.Plugs.System
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Factorial
|
#region Factorial (only used in Sin(), not plug )
|
||||||
public static int Factorial(int n)
|
public static int Factorial(int n)
|
||||||
{
|
{
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
|
|
@ -330,24 +192,21 @@ namespace Cosmos.System.Plugs.System
|
||||||
|
|
||||||
#region Ceiling
|
#region Ceiling
|
||||||
public static double Ceiling(double a)
|
public static double Ceiling(double a)
|
||||||
{
|
{ // should be using assembler for bigger values than int or long max
|
||||||
int returnval = (int)Floor(a);
|
if (a == Double.NaN || a == Double.NegativeInfinity || a == Double.PositiveInfinity)
|
||||||
returnval += 1;
|
return a;
|
||||||
return returnval;
|
int i = (a - (int)a > 0) ? (int)(a + 1) : (int)a;
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Floor
|
#region Floor
|
||||||
public static double Floor(double a)
|
public static double Floor(double a)
|
||||||
{
|
{ // should be using assembler for bigger values than int or long max
|
||||||
int returnval = (int)a;
|
if (a == Double.NaN || a == Double.NegativeInfinity || a == Double.PositiveInfinity)
|
||||||
|
return a;
|
||||||
if (a < 0)
|
int i = (a - (int)a < 0) ? (int)(a - 1) : (int)a;
|
||||||
{
|
return i;
|
||||||
returnval -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnval;
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue