From 2d95847a925787492a62d88040ee302d73b19b68 Mon Sep 17 00:00:00 2001 From: xgopilot Date: Wed, 22 Oct 2025 02:05:09 +0000 Subject: [PATCH] Add comprehensive type conversion tests for issue #961 - Add integer conversion tests (signed/unsigned, truncation, extension) - Add float conversion tests (precision loss, special values, overflow) - Add untyped constant conversion tests - Add overflow and wrapping behavior tests These tests cover the gaps identified in the code review: 1. Signed/unsigned conversions with negative values 2. Truncation from larger to smaller integer types 3. Sign extension vs zero extension 4. Float-to-int conversions with overflow/saturation 5. Int-to-float conversions with precision loss 6. Untyped constants with typed variables 7. Integer overflow and wrapping behavior 8. Special float values (Inf, NaN) Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: cpunion --- _cmptest/conversion_float/float_conv.go | 107 ++++++++++++++++ _cmptest/conversion_int/int_conv.go | 66 ++++++++++ _cmptest/conversion_overflow/overflow.go | 131 ++++++++++++++++++++ _cmptest/conversion_untyped/untyped_conv.go | 117 +++++++++++++++++ 4 files changed, 421 insertions(+) create mode 100644 _cmptest/conversion_float/float_conv.go create mode 100644 _cmptest/conversion_int/int_conv.go create mode 100644 _cmptest/conversion_overflow/overflow.go create mode 100644 _cmptest/conversion_untyped/untyped_conv.go diff --git a/_cmptest/conversion_float/float_conv.go b/_cmptest/conversion_float/float_conv.go new file mode 100644 index 00000000..b68b3f8b --- /dev/null +++ b/_cmptest/conversion_float/float_conv.go @@ -0,0 +1,107 @@ +package main + +import ( + "fmt" + "math" +) + +func main() { + fmt.Println("=== Float Type Conversions ===") + + // 1. Float32 <-> Float64 precision + fmt.Println("\n1. Float32 <-> Float64 Precision:") + var f64 float64 = 1.23456789012345678901234567890 + var f32 float32 = float32(f64) + var f64_2 float64 = float64(f32) + fmt.Printf("float64: %.20f\n", f64) + fmt.Printf("-> float32: %.20f\n", f32) + fmt.Printf("-> float64: %.20f\n", f64_2) + + // 2. Special values + fmt.Println("\n2. Special Float Values:") + var inf64 float64 = math.Inf(1) + var inf32 float32 = float32(inf64) + fmt.Printf("float64(+Inf) -> float32: %v\n", inf32) + + var negInf64 float64 = math.Inf(-1) + var negInf32 float32 = float32(negInf64) + fmt.Printf("float64(-Inf) -> float32: %v\n", negInf32) + + var nan64 float64 = math.NaN() + var nan32 float32 = float32(nan64) + fmt.Printf("float64(NaN) -> float32: %v\n", nan32) + + // 3. Float to Int conversions (normal range) + fmt.Println("\n3. Float to Int (Normal Range):") + var f1 float64 = 123.456 + fmt.Printf("float64(123.456) -> int32: %d\n", int32(f1)) + fmt.Printf("float64(123.456) -> uint32: %d\n", uint32(f1)) + + var f_neg float64 = -123.456 + fmt.Printf("float64(-123.456) -> int32: %d\n", int32(f_neg)) + + // 4. Float to Int conversions (overflow/saturation) + fmt.Println("\n4. Float to Int (Overflow/Saturation):") + var f2 float64 = 1e20 + fmt.Printf("float64(1e20) -> int32: %d\n", int32(f2)) + fmt.Printf("float64(1e20) -> int8: %d\n", int8(f2)) + fmt.Printf("float64(1e20) -> uint32: %d\n", uint32(f2)) + + var f3 float64 = -1e20 + fmt.Printf("float64(-1e20) -> int32: %d\n", int32(f3)) + fmt.Printf("float64(-1e20) -> int8: %d\n", int8(f3)) + + // 5. Negative float to unsigned + fmt.Println("\n5. Negative Float to Unsigned:") + var f4 float64 = -123.456 + fmt.Printf("float64(-123.456) -> uint32: %d\n", uint32(f4)) + fmt.Printf("float64(-123.456) -> uint8: %d\n", uint8(f4)) + + // 6. Special float values to int + fmt.Println("\n6. Special Float Values to Int:") + var fInf float64 = math.Inf(1) + fmt.Printf("float64(+Inf) -> int32: %d\n", int32(fInf)) + + var fNegInf float64 = math.Inf(-1) + fmt.Printf("float64(-Inf) -> int32: %d\n", int32(fNegInf)) + + var fNaN float64 = math.NaN() + fmt.Printf("float64(NaN) -> int32: %d\n", int32(fNaN)) + + // 7. Int to Float conversions (precision loss) + fmt.Println("\n7. Int to Float (Precision Loss):") + var i1 int64 = 9007199254740993 // 2^53 + 1 + var ff1 float64 = float64(i1) + fmt.Printf("int64(9007199254740993) -> float64: %.0f\n", ff1) + fmt.Printf("Precision lost: %v\n", int64(ff1) != i1) + + var i2 int32 = 16777217 // 2^24 + 1 + var ff2 float32 = float32(i2) + fmt.Printf("int32(16777217) -> float32: %.0f\n", ff2) + fmt.Printf("Precision lost: %v\n", int32(ff2) != i2) + + // 8. Large uint32 to float to int32 (the bug case) + fmt.Println("\n8. Large Uint32 -> Float64 -> Int32:") + var bigUint32 uint32 = 0xFFFFFFFF + var fBig float64 = float64(bigUint32) + var iBig int32 = int32(fBig) + fmt.Printf("uint32(0xFFFFFFFF) = %d\n", bigUint32) + fmt.Printf("-> float64 = %.0f\n", fBig) + fmt.Printf("-> int32 = %d\n", iBig) + + // 9. Unsigned to float conversions + fmt.Println("\n9. Unsigned to Float:") + var u32 uint32 = 4000000000 + var fU32_32 float32 = float32(u32) + var fU32_64 float64 = float64(u32) + fmt.Printf("uint32(4000000000) -> float32: %.0f\n", fU32_32) + fmt.Printf("uint32(4000000000) -> float64: %.0f\n", fU32_64) + + // 10. Signed to float conversions + fmt.Println("\n10. Signed to Float:") + var s32 int32 = -2147483648 // MinInt32 + var fS32_32 float32 = float32(s32) + var fS32_64 float64 = float64(s32) + fmt.Printf("int32(MinInt32) -> float32: %.0f\n", fS32_32) + fmt.Printf("int32(MinInt32) -> float64: %.0f\n", fS32_64) +} diff --git a/_cmptest/conversion_int/int_conv.go b/_cmptest/conversion_int/int_conv.go new file mode 100644 index 00000000..7f27eeca --- /dev/null +++ b/_cmptest/conversion_int/int_conv.go @@ -0,0 +1,66 @@ +package main + +import "fmt" + +func main() { + fmt.Println("=== Integer Type Conversions ===") + + // 1. Signed/Unsigned conversions + fmt.Println("\n1. Negative to Unsigned:") + var negInt int32 = -1 + fmt.Printf("int32(-1) -> uint32: %d (0x%X)\n", uint32(negInt), uint32(negInt)) + fmt.Printf("int32(-1) -> uint8: %d (0x%X)\n", uint8(negInt), uint8(negInt)) + + var negInt64 int64 = -1234567890 + fmt.Printf("int64(-1234567890) -> uint32: %d (0x%X)\n", uint32(negInt64), uint32(negInt64)) + + // 2. Large unsigned to signed + fmt.Println("\n2. Large Unsigned to Signed:") + var bigUint uint32 = 0xFFFFFFFF + fmt.Printf("uint32(0xFFFFFFFF) -> int32: %d\n", int32(bigUint)) + fmt.Printf("uint32(0xFFFFFFFF) -> int16: %d\n", int16(bigUint)) + + var bigUint64 uint64 = 0xFFFFFFFFFFFFFFFF + fmt.Printf("uint64(max) -> int32: %d\n", int32(bigUint64)) + + // 3. Truncation (downward conversion) + fmt.Println("\n3. Truncation (Larger to Smaller):") + var i64 int64 = 0x123456789ABC + fmt.Printf("int64(0x123456789ABC) -> int32: 0x%X\n", int32(i64)) + fmt.Printf("int64(0x123456789ABC) -> int16: 0x%X\n", int16(i64)) + fmt.Printf("int64(0x123456789ABC) -> int8: 0x%X\n", int8(i64)) + + var u64 uint64 = 0xFFFFFFFFFFFFFFFF + fmt.Printf("uint64(max) -> uint32: 0x%X\n", uint32(u64)) + fmt.Printf("uint64(max) -> uint16: 0x%X\n", uint16(u64)) + fmt.Printf("uint64(max) -> uint8: 0x%X\n", uint8(u64)) + + // 4. Sign extension vs zero extension + fmt.Println("\n4. Sign Extension vs Zero Extension:") + var i8 int8 = -1 + fmt.Printf("int8(-1) -> int16: %d (0x%04X)\n", int16(i8), uint16(int16(i8))) + fmt.Printf("int8(-1) -> int32: %d (0x%08X)\n", int32(i8), uint32(int32(i8))) + fmt.Printf("int8(-1) -> int64: %d (0x%016X)\n", int64(i8), uint64(int64(i8))) + + var u8 uint8 = 0xFF + fmt.Printf("uint8(0xFF) -> uint16: %d (0x%04X)\n", uint16(u8), uint16(u8)) + fmt.Printf("uint8(0xFF) -> uint32: %d (0x%08X)\n", uint32(u8), uint32(u8)) + + // 5. Mixed sign conversions with specific values + fmt.Println("\n5. Mixed Sign Conversions:") + var si16 int16 = -32768 // MinInt16 + fmt.Printf("int16(MinInt16) -> uint16: %d\n", uint16(si16)) + + var su16 uint16 = 32768 + fmt.Printf("uint16(32768) -> int16: %d\n", int16(su16)) + + // 6. Boundary values + fmt.Println("\n6. Boundary Value Conversions:") + var maxI8 int8 = 127 + var minI8 int8 = -128 + fmt.Printf("int8(MaxInt8=%d) -> uint8: %d\n", maxI8, uint8(maxI8)) + fmt.Printf("int8(MinInt8=%d) -> uint8: %d\n", minI8, uint8(minI8)) + + var maxU8 uint8 = 255 + fmt.Printf("uint8(MaxUint8=%d) -> int8: %d\n", maxU8, int8(maxU8)) +} diff --git a/_cmptest/conversion_overflow/overflow.go b/_cmptest/conversion_overflow/overflow.go new file mode 100644 index 00000000..3f706695 --- /dev/null +++ b/_cmptest/conversion_overflow/overflow.go @@ -0,0 +1,131 @@ +package main + +import "fmt" + +func main() { + fmt.Println("=== Overflow and Wrapping Behavior ===") + + // 1. Signed integer overflow + fmt.Println("\n1. Signed Integer Overflow:") + var i8max int8 = 127 + var i8min int8 = -128 + fmt.Printf("int8 max (127) + 1 = %d\n", i8max+1) + fmt.Printf("int8 max (127) + 2 = %d\n", i8max+2) + fmt.Printf("int8 min (-128) - 1 = %d\n", i8min-1) + fmt.Printf("int8 min (-128) - 2 = %d\n", i8min-2) + + var i16max int16 = 32767 + var i16min int16 = -32768 + fmt.Printf("int16 max (32767) + 1 = %d\n", i16max+1) + fmt.Printf("int16 min (-32768) - 1 = %d\n", i16min-1) + + var i32max int32 = 2147483647 + var i32min int32 = -2147483648 + fmt.Printf("int32 max + 1 = %d\n", i32max+1) + fmt.Printf("int32 min - 1 = %d\n", i32min-1) + + // 2. Unsigned integer overflow + fmt.Println("\n2. Unsigned Integer Overflow:") + var u8max uint8 = 255 + fmt.Printf("uint8 max (255) + 1 = %d\n", u8max+1) + fmt.Printf("uint8 max (255) + 2 = %d\n", u8max+2) + fmt.Printf("uint8(0) - 1 = %d\n", uint8(0)-1) + + var u16max uint16 = 65535 + fmt.Printf("uint16 max (65535) + 1 = %d\n", u16max+1) + fmt.Printf("uint16(0) - 1 = %d\n", uint16(0)-1) + + var u32max uint32 = 4294967295 + fmt.Printf("uint32 max + 1 = %d\n", u32max+1) + fmt.Printf("uint32(0) - 1 = %d\n", uint32(0)-1) + + // 3. Multiplication overflow + fmt.Println("\n3. Multiplication Overflow:") + var mi8 int8 = 64 + fmt.Printf("int8(64) * 2 = %d\n", mi8*2) + fmt.Printf("int8(64) * 3 = %d\n", mi8*3) + + var mi16 int16 = 256 + fmt.Printf("int16(256) * 128 = %d\n", mi16*128) + fmt.Printf("int16(256) * 256 = %d\n", mi16*256) + + // 4. Subtraction underflow + fmt.Println("\n4. Subtraction Underflow:") + var s8 int8 = -100 + fmt.Printf("int8(-100) - 30 = %d\n", s8-30) + fmt.Printf("int8(-100) - 50 = %d\n", s8-50) + + // 5. Mixed operations causing overflow + fmt.Println("\n5. Mixed Operations Causing Overflow:") + var m1 int8 = 100 + var m2 int8 = 50 + fmt.Printf("int8(100) + int8(50) = %d\n", m1+m2) + + var m3 int8 = 127 + var m4 int8 = 1 + fmt.Printf("int8(127) + int8(1) = %d\n", m3+m4) + + // 6. Boundary arithmetic + fmt.Println("\n6. Boundary Value Arithmetic:") + var b1 int8 = 127 + var b2 int8 = 127 + fmt.Printf("int8(127) + int8(127) = %d\n", b1+b2) + + var b3 int8 = -128 + var b4 int8 = -128 + fmt.Printf("int8(-128) + int8(-128) = %d\n", b3+b4) + + // 7. Division edge cases + fmt.Println("\n7. Division Edge Cases:") + var d1 int8 = -128 + var d2 int8 = -1 + fmt.Printf("int8(-128) / int8(-1) = %d\n", d1/d2) + + var d3 int32 = -2147483648 + var d4 int32 = -1 + fmt.Printf("int32(MinInt32) / int32(-1) = %d\n", d3/d4) + + // 8. Negation overflow + fmt.Println("\n8. Negation Overflow:") + var n1 int8 = -128 + fmt.Printf("-int8(-128) = %d\n", -n1) + + var n2 int32 = -2147483648 + fmt.Printf("-int32(MinInt32) = %d\n", -n2) + + // 9. Shift operations with overflow + fmt.Println("\n9. Shift Operations:") + var sh1 int8 = 1 + fmt.Printf("int8(1) << 7 = %d\n", sh1<<7) + fmt.Printf("int8(1) << 8 = %d\n", sh1<<8) + + var sh2 int16 = 1 + fmt.Printf("int16(1) << 15 = %d\n", sh2<<15) + fmt.Printf("int16(1) << 16 = %d\n", sh2<<16) + + // 10. Increment/decrement at boundaries + fmt.Println("\n10. Increment/Decrement at Boundaries:") + var inc1 int8 = 126 + inc1++ + fmt.Printf("int8(126)++ = %d\n", inc1) + inc1++ + fmt.Printf("int8(127)++ = %d\n", inc1) + + var dec1 int8 = -127 + dec1-- + fmt.Printf("int8(-127)-- = %d\n", dec1) + dec1-- + fmt.Printf("int8(-128)-- = %d\n", dec1) + + var inc2 uint8 = 254 + inc2++ + fmt.Printf("uint8(254)++ = %d\n", inc2) + inc2++ + fmt.Printf("uint8(255)++ = %d\n", inc2) + + var dec2 uint8 = 1 + dec2-- + fmt.Printf("uint8(1)-- = %d\n", dec2) + dec2-- + fmt.Printf("uint8(0)-- = %d\n", dec2) +} diff --git a/_cmptest/conversion_untyped/untyped_conv.go b/_cmptest/conversion_untyped/untyped_conv.go new file mode 100644 index 00000000..c0bfc42a --- /dev/null +++ b/_cmptest/conversion_untyped/untyped_conv.go @@ -0,0 +1,117 @@ +package main + +import "fmt" + +func main() { + fmt.Println("=== Untyped Constant Conversions ===") + + // 1. Untyped int with typed variables + fmt.Println("\n1. Untyped Int with Typed Variables:") + const untypedInt = 42 + var i8 int8 = 100 + var i16 int16 = 1000 + var i32 int32 = 70000 + var i64 int64 = 1 << 32 + + fmt.Printf("untypedInt(42) + int8(100): %d (type %T)\n", untypedInt+i8, untypedInt+i8) + fmt.Printf("untypedInt(42) + int16(1000): %d (type %T)\n", untypedInt+i16, untypedInt+i16) + fmt.Printf("untypedInt(42) + int32(70000): %d (type %T)\n", untypedInt+i32, untypedInt+i32) + fmt.Printf("untypedInt(42) + int64(1<<32): %d (type %T)\n", untypedInt+i64, untypedInt+i64) + + // 2. Untyped float with typed variables + fmt.Println("\n2. Untyped Float with Typed Variables:") + const untypedFloat = 3.14 + var f32 float32 = 2.5 + var f64 float64 = 2.5 + + fmt.Printf("untypedFloat(3.14) + float32(2.5): %f (type %T)\n", untypedFloat+f32, untypedFloat+f32) + fmt.Printf("untypedFloat(3.14) + float64(2.5): %f (type %T)\n", untypedFloat+f64, untypedFloat+f64) + + // 3. Untyped complex with typed variables + fmt.Println("\n3. Untyped Complex with Typed Variables:") + const untypedComplex = 1 + 2i + var c64 complex64 = 1 + 2i + var c128 complex128 = 1 + 2i + + fmt.Printf("untypedComplex(1+2i) + complex64(1+2i): %v (type %T)\n", untypedComplex+c64, untypedComplex+c64) + fmt.Printf("untypedComplex(1+2i) + complex128(1+2i): %v (type %T)\n", untypedComplex+c128, untypedComplex+c128) + + // 4. Untyped bool + fmt.Println("\n4. Untyped Bool:") + const untypedBool = true + const untypedBoolFalse = false + var b1 bool = untypedBool + var b2 bool = untypedBoolFalse + fmt.Printf("untypedBool(true): %v (type %T)\n", b1, b1) + fmt.Printf("untypedBool(false): %v (type %T)\n", b2, b2) + + // 5. Untyped string + fmt.Println("\n5. Untyped String:") + const untypedString = "hello" + var s1 string = untypedString + fmt.Printf("untypedString: %s (type %T)\n", s1, s1) + + // 6. Untyped rune + fmt.Println("\n6. Untyped Rune:") + const untypedRune = 'A' + var r1 rune = untypedRune + var r2 int32 = untypedRune + fmt.Printf("untypedRune('A'): %c = %d (type %T)\n", r1, r1, r1) + fmt.Printf("untypedRune('A') as int32: %d (type %T)\n", r2, r2) + + // 7. Untyped constant expressions + fmt.Println("\n7. Untyped Constant Expressions:") + const c1 = 1 << 10 + const c2 = c1 * 1024 + const c3 = float64(c2) / 3.0 + const c4 = int(c3) + + fmt.Printf("1 << 10 = %d\n", c1) + fmt.Printf("(1 << 10) * 1024 = %d\n", c2) + fmt.Printf("float64(c2) / 3.0 = %f\n", c3) + fmt.Printf("int(c3) = %d\n", c4) + + // 8. Untyped operations + fmt.Println("\n8. Untyped Operations:") + const a = 100 + const b = 200 + const c = a + b + const d = a * b + const e = b / a + const f = b % a + + fmt.Printf("100 + 200 = %d\n", c) + fmt.Printf("100 * 200 = %d\n", d) + fmt.Printf("200 / 100 = %d\n", e) + fmt.Printf("200 %% 100 = %d\n", f) + + // 9. Mixed untyped and typed in expressions + fmt.Println("\n9. Mixed Untyped and Typed in Expressions:") + const uConst = 10 + var v1 int8 = 5 + var v2 int16 = 10 + var v3 int32 = 20 + + // These should take the type of the typed variable + var result1 = uConst + v1 + var result2 = uConst + v2 + var result3 = uConst + v3 + + fmt.Printf("const(10) + int8(5) = %d (type %T)\n", result1, result1) + fmt.Printf("const(10) + int16(10) = %d (type %T)\n", result2, result2) + fmt.Printf("const(10) + int32(20) = %d (type %T)\n", result3, result3) + + // 10. Untyped zero values + fmt.Println("\n10. Untyped Zero Values:") + const zero = 0 + const zeroFloat = 0.0 + const emptyString = "" + + var iz int32 = zero + var fz float64 = zeroFloat + var sz string = emptyString + + fmt.Printf("untyped 0 -> int32: %d (type %T)\n", iz, iz) + fmt.Printf("untyped 0.0 -> float64: %f (type %T)\n", fz, fz) + fmt.Printf("untyped \"\" -> string: %q (type %T)\n", sz, sz) +}