Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions std/cpp/_std/haxe/numeric/Int64Native.hx
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ private abstract Int64NativeImpl(cpp.Int64) from cpp.Int64 to cpp.Int64 {
public static function ushr(a:Int64Native, b:Int):Int64Native;
public function toString():String;
public static function parseString(sParam:String):Int64Native;
public static function toFloat(x:Int64Native):Float;
public static function fromFloat(f:Float):Int64Native;
#else
public var high(get, never):haxe.Int32;
Expand All @@ -165,8 +166,6 @@ private abstract Int64NativeImpl(cpp.Int64) from cpp.Int64 to cpp.Int64 {
}

public static #if !scriptable inline #end function toInt(x:Int64Native):Int {
if (x.high != x.low >> 31)
throw "Overflow";
return x.low;
}

Expand Down Expand Up @@ -241,6 +240,13 @@ private abstract Int64NativeImpl(cpp.Int64) from cpp.Int64 to cpp.Int64 {
return haxe.numeric.Int64Helper.fromFloat(f);
}

public static #if !scriptable inline #end function toFloat(x:Int64Native):Float {
var f:Float = x.low;
if (f < 0)
f += 4294967296.0;
return (x.high : Float) * 4294967296.0 + f;
}

public static function udivMod(dividend:Int64Native, divisor:Int64Native):{quotient:Int64Native, modulus:Int64Native} {
return haxe.numeric.UInt64Helper.udivMod(dividend, divisor);
}
Expand Down
6 changes: 0 additions & 6 deletions std/cpp/cppia/HostClasses.hx
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,6 @@ class HostClasses {
externs.set("Sys", true);
externs.set("haxe.IMap", true);
externs.set("haxe.crypto.HashMethod", true);
externs.set("haxe._Int64.Int64_Impl_", true);
externs.set("haxe._Int64.___Int64", true);
externs.set("haxe._Int32.Int32_Impl_", true);
externs.set("haxe._Int32.___Int32", true);
// Hidden in implementation classes
// externs.set("sys.db.RecordType",true);
externs.set("sys.net._Socket.SocketInput", true);
Expand Down Expand Up @@ -229,8 +225,6 @@ class HostClasses {
Compiler.keep("haxe.crypto.HashMethod");
Compiler.keep("haxe._Int64.Int64_Impl_");
Compiler.keep("haxe._Int32.Int32_Impl_");
Compiler.keep("haxe._Int64.___Int64");
Compiler.keep("haxe._Int32.___Int32");
for (cls in classes) {
Context.getModule(cls);
Compiler.keep(cls);
Expand Down
11 changes: 8 additions & 3 deletions std/eval/_std/haxe/numeric/Int64Native.hx
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ private abstract Int64NativeImpl(EvalInt64) from EvalInt64 to EvalInt64 {
return EvalInt64.ofInt(x);
}

public static function toInt(x:Int64Native):Int {
if (x.high != x.low >> 31)
throw "Overflow";
public static inline function toInt(x:Int64Native):Int {
var v:EvalInt64 = x;
return v.toInt();
}
Expand Down Expand Up @@ -151,6 +149,13 @@ private abstract Int64NativeImpl(EvalInt64) from EvalInt64 to EvalInt64 {
return haxe.numeric.Int64Helper.fromFloat(f);
}

public static inline function toFloat(x:Int64Native):Float {
var f:Float = x.low;
if (f < 0)
f += 4294967296.0;
return (x.high : Float) * 4294967296.0 + f;
}

public static function udivMod(dividend:Int64Native, divisor:Int64Native):{quotient:Int64Native, modulus:Int64Native} {
return haxe.numeric.UInt64Helper.udivMod(dividend, divisor);
}
Expand Down
6 changes: 6 additions & 0 deletions std/haxe/Int32.hx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ abstract Int32(Int32Native) from Int to Int {
private inline function new(x:Int32Native)
this = x;

/** The greatest representable Int32 value: `2^31 - 1`. **/
public static final MAX:Int32 = 0x7FFFFFFF;

/** The smallest representable Int32 value: `-2^31`. **/
public static final MIN:Int32 = 0x80000000;

@:op(-A) private static inline function neg(x:Int32):Int32
return Int32Native.neg(x);

Expand Down
18 changes: 16 additions & 2 deletions std/haxe/Int64.hx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ abstract Int64(Int64Native) from Int64Native to Int64Native {
private inline function new(x:Int64Native)
this = x;

/** The greatest representable Int64 value: `2^63 - 1`. **/
public static final MAX:Int64 = make(0x7FFFFFFF, 0xFFFFFFFF);

/** The smallest representable Int64 value: `-2^63`. **/
public static final MIN:Int64 = make(0x80000000, 0);

/**
Makes a copy of `this` Int64.
**/
Expand All @@ -60,8 +66,8 @@ abstract Int64(Int64Native) from Int64Native to Int64Native {
return new Int64(Int64Native.ofInt(x));

/**
Returns an Int with the value of the Int64 `x`.
Throws an exception if `x` cannot be represented in 32 bits.
Returns an Int with the low 32 bits of the Int64 `x`.
The high 32 bits are discarded.
**/
public static inline function toInt(x:Int64):Int
return Int64Native.toInt(x);
Expand Down Expand Up @@ -136,6 +142,14 @@ abstract Int64(Int64Native) from Int64Native to Int64Native {
return Int64Native.fromFloat(f);
}

/**
Converts this Int64 to a Float.
Values between -2^53 and 2^53 are exact; larger values may lose precision.
**/
public inline function toFloat():Float {
return Int64Native.toFloat(this);
}

/**
Performs signed integer division of `dividend` by `divisor`.
Returns `{ quotient : Int64, modulus : Int64 }`.
Expand Down
6 changes: 6 additions & 0 deletions std/haxe/UInt64.hx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ abstract UInt64(Int64Native) from Int64Native to Int64Native {
private inline function new(x:Int64Native)
this = x;

/** The greatest representable UInt64 value: `2^64 - 1`. **/
public static final MAX:UInt64 = make(0xFFFFFFFF, 0xFFFFFFFF);

/** The smallest representable UInt64 value: `0`. **/
public static final MIN:UInt64 = make(0, 0);

/**
Makes a copy of `this` UInt64.
**/
Expand Down
10 changes: 7 additions & 3 deletions std/haxe/numeric/Int64Native.hx
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ private class Int64NativeImpl {
}

public static inline function toInt(x:Int64Native):Int {
if (x.high != x.low >> 31)
throw "Overflow";

return x.low;
}

Expand Down Expand Up @@ -314,6 +311,13 @@ private class Int64NativeImpl {
return haxe.numeric.Int64Helper.fromFloat(f);
}

public static inline function toFloat(x:Int64Native):Float {
var f:Float = x.low;
if (f < 0)
f += 4294967296.0;
return (x.high : Float) * 4294967296.0 + f;
}

@:ifFeature("dynamic_read.toString")
public function toString():String {
if (high == 0 && low == 0)
Expand Down
9 changes: 5 additions & 4 deletions std/hl/_std/haxe/numeric/Int64Native.hx
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ private abstract Int64NativeImpl(hl.I64) from hl.I64 to hl.I64 {
}

public static inline function toInt(x:Int64Native):Int {
var v:hl.I64 = x;
if (v < (cast -2147483648 : hl.I64) || v > (cast 2147483647 : hl.I64))
throw "Overflow";
return cast v;
return cast(x : hl.I64);
}

public static inline function isInt64(val:Dynamic):Bool
Expand Down Expand Up @@ -148,6 +145,10 @@ private abstract Int64NativeImpl(hl.I64) from hl.I64 to hl.I64 {
return haxe.numeric.Int64Helper.fromFloat(f);
}

public static inline function toFloat(x:Int64Native):Float {
return cast(x : hl.I64);
}

public static function udivMod(dividend:Int64Native, divisor:Int64Native):{quotient:Int64Native, modulus:Int64Native} {
return haxe.numeric.UInt64Helper.udivMod(dividend, divisor);
}
Expand Down
10 changes: 5 additions & 5 deletions std/jvm/_std/haxe/numeric/Int64Native.hx
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,7 @@ private abstract Int64NativeImpl(jvm.Int64) from jvm.Int64 to jvm.Int64 {
}

public static inline function toInt(x:Int64Native):Int {
var v:jvm.Int64 = x;
if (v < ((cast -2147483648 : jvm.Int64))
|| v > ((cast 2147483647 : jvm.Int64)))
throw "Overflow";
return cast v;
return cast(x : jvm.Int64);
}

public static inline function isInt64(val:Dynamic):Bool
Expand Down Expand Up @@ -151,6 +147,10 @@ private abstract Int64NativeImpl(jvm.Int64) from jvm.Int64 to jvm.Int64 {
return haxe.numeric.Int64Helper.fromFloat(f);
}

public static inline function toFloat(x:Int64Native):Float {
return cast(x : jvm.Int64);
}

public static function udivMod(dividend:Int64Native, divisor:Int64Native):{quotient:Int64Native, modulus:Int64Native} {
return haxe.numeric.UInt64Helper.udivMod(dividend, divisor);
}
Expand Down
9 changes: 7 additions & 2 deletions tests/unit/src/unit/TestInt32.hx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ import haxe.Int32;

class TestInt32 extends Test {
// --- Constants ---
static var MAX:Int32 = 0x7fffffff;
static var MIN:Int32 = 0x80000000;
static var MAX:Int32 = Int32.MAX;
static var MIN:Int32 = Int32.MIN;
static var ZERO:Int32 = 0;
static var ONE:Int32 = 1;
static var NEG_ONE:Int32 = -1;

function testMinMax() {
eq((Int32.MAX : Int32), (0x7fffffff : Int32));
eq((Int32.MIN : Int32), (0x80000000 : Int32));
}

// --- Overflow behavior ---
function testOverflowAdd() {
eq((MAX + ONE : Int32), MIN);
Expand Down
55 changes: 49 additions & 6 deletions tests/unit/src/unit/TestInt64.hx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class TestInt64 extends Test {
a = Int64.make(0,0x80000000);
eq( a.high, 0 );
eq( a.low, 0x80000000 );
exc( tryOverflow.bind(a) ); // Throws Overflow
// toInt truncates: discards high 32 bits, returns low
eq( a.toInt(), 0x80000000 );

a = Int64.make(0xFFFFFFFF,0x80000000);
eq( a.high, 0xFFFFFFFF );
Expand All @@ -44,7 +45,8 @@ class TestInt64 extends Test {
a = Int64.make(0xFFFFFFFF,0x7FFFFFFF);
eq( a.high, 0xFFFFFFFF );
eq( a.low, 0x7FFFFFFF );
exc( tryOverflow.bind(a) ); // Throws Overflow
// toInt truncates: discards high 32 bits, returns low
eq( a.toInt(), 0x7FFFFFFF );
}

public function testNegateOverflow_Issue7485()
Expand Down Expand Up @@ -89,10 +91,6 @@ class TestInt64 extends Test {
eq(n.low, 0xefefefef);
}

function tryOverflow(a:Int64) {
a.toInt();
}

public function testIncrement() {
var a:Int64, b:Int64, c:Int64;

Expand Down Expand Up @@ -565,6 +563,51 @@ class TestInt64 extends Test {
}
}

public function testToFloat() {
// Zero
feq(Int64.make(0, 0).toFloat(), 0.0);

// Positive values
feq(Int64.ofInt(1).toFloat(), 1.0);
feq(Int64.ofInt(100).toFloat(), 100.0);

// Negative values
feq(Int64.ofInt(-1).toFloat(), -1.0);
feq(Int64.ofInt(-100).toFloat(), -100.0);

// Boundary: MAX_SAFE_INTEGER (2^53 - 1) — exact
feq(Int64.parseString("9007199254740991").toFloat(), 9007199254740991.0);
feq(Int64.parseString("-9007199254740991").toFloat(), -9007199254740991.0);

// Int32 boundaries
feq(Int64.ofInt(2147483647).toFloat(), 2147483647.0);
feq(Int64.ofInt(-2147483648).toFloat(), -2147483648.0);

// Large positive: 2^32 = 4294967296
feq(Int64.make(1, 0).toFloat(), 4294967296.0);

// MAX and MIN: large values, may not be exact but roundtrip should be close
var maxFloat = Int64.MAX.toFloat();
t(maxFloat > 9.22e18);

var minFloat = Int64.MIN.toFloat();
t(minFloat < -9.22e18);
}

public function testMinMax() {
int64eq(Int64.MAX, Int64.make(0x7FFFFFFF, 0xFFFFFFFF));
int64eq(Int64.MIN, Int64.make(0x80000000, 0));

// MAX + 1 wraps to MIN
int64eq(Int64.MAX + Int64.ofInt(1), Int64.MIN);
// MIN - 1 wraps to MAX
int64eq(Int64.MIN - Int64.ofInt(1), Int64.MAX);

// String representations
eq(Std.string(Int64.MAX), "9223372036854775807");
eq(Std.string(Int64.MIN), "-9223372036854775808");
}

static function toHex(v:haxe.Int64) {
return "0x" + (v.high == 0 ? StringTools.hex(v.low) : StringTools.hex(v.high) + StringTools.hex(v.low, 8));
}
Expand Down
13 changes: 13 additions & 0 deletions tests/unit/src/unit/TestUInt64.hx
Original file line number Diff line number Diff line change
Expand Up @@ -419,4 +419,17 @@ class TestUInt64 extends Test {
function uint64eq(v:UInt64, v2:UInt64, ?pos:haxe.PosInfos) {
t(v == v2, pos);
}

public function testMinMax() {
uint64eq(UInt64.MIN, UInt64.make(0, 0));
uint64eq(UInt64.MAX, UInt64.make(0xFFFFFFFF, 0xFFFFFFFF));

// MAX + 1 wraps to 0 (MIN)
uint64eq(UInt64.MAX + UInt64.ofInt(1), UInt64.MIN);
// MIN - 1 wraps to MAX
uint64eq(UInt64.MIN - UInt64.ofInt(1), UInt64.MAX);

eq(Std.string(UInt64.MIN), "0");
eq(Std.string(UInt64.MAX), "18446744073709551615");
}
}
4 changes: 4 additions & 0 deletions tests/unit/src/unit/teststd/haxe/TestInt32.hx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ class TestInt32 extends unit.Test {
var max:haxe.Int32 = 0x7fffffff;
var min:haxe.Int32 = 0x80000000;

// MIN/MAX constants match expected values
eq(haxe.Int32.MAX, max);
eq(haxe.Int32.MIN, min);

var a:haxe.Int32 = 0x7fffffff;
eq(a++, max);
eq(a, min);
Expand Down
Loading