Description
giga/thicc (long/long long) values are now stored as real 64-bit integers (#282), but the conversion paths to chad/gigachad (float/double) still read the 32-bit slot, truncating the value to its low 32 bits. This happens both for a plain assignment/promotion of a giga identifier to a floating type and for mixed giga * double-style arithmetic.
The #282 fix covered storage and integer-context evaluation but did not cover the floating-point conversion paths, so these reproduce today.
Minimal reproduction code
skibidi main {
giga rizz a = 5000000000;
gigachad d = a; // widening giga -> double
yapping("%f", d); // expect 5000000000.000000
bussin 0;
}
Mixed arithmetic:
skibidi main {
giga rizz a = 5000000000;
gigachad d = 2.0;
yapping("%f", a * d); // expect 10000000000.000000
bussin 0;
}
Expected behavior
5000000000.000000 and 10000000000.000000 respectively.
Actual behavior
$ ./brainrot assign.brainrot
705032704.000000
$ ./brainrot mixed.brainrot
1410065408.000000
705032704 = 5000000000 mod 2^32 — the high 32 bits are dropped.
Brainrot version / commit
19b9563
Operating system
Ubuntu on WSL2 (Linux 5.15)
Additional context
Root cause: ast.c.
handle_identifier, the promote-to-double (promote == 1) and promote-to-float (promote == 2) paths: the VAR_INT/VAR_ENUM arms read var->value.ivalue (the 32-bit slot) rather than var->value.llvalue, without checking the is_long/is_long_long modifiers.
handle_binary_operation: promoted_type has no 64-bit category, so when the other operand forces float/double promotion, a giga/thicc operand (whose type is VAR_INT, with long-ness only in modifiers) is fetched via (double)evaluate_expression_int(...) / (float)evaluate_expression_int(...), which narrows to 32 bits before the widening conversion.
Follow-on from #282.
Description
giga/thicc(long/long long) values are now stored as real 64-bit integers (#282), but the conversion paths tochad/gigachad(float/double) still read the 32-bit slot, truncating the value to its low 32 bits. This happens both for a plain assignment/promotion of agigaidentifier to a floating type and for mixedgiga * double-style arithmetic.The #282 fix covered storage and integer-context evaluation but did not cover the floating-point conversion paths, so these reproduce today.
Minimal reproduction code
Mixed arithmetic:
Expected behavior
5000000000.000000and10000000000.000000respectively.Actual behavior
705032704 = 5000000000 mod 2^32— the high 32 bits are dropped.Brainrot version / commit
19b9563
Operating system
Ubuntu on WSL2 (Linux 5.15)
Additional context
Root cause:
ast.c.handle_identifier, the promote-to-double (promote == 1) and promote-to-float (promote == 2) paths: theVAR_INT/VAR_ENUMarms readvar->value.ivalue(the 32-bit slot) rather thanvar->value.llvalue, without checking theis_long/is_long_longmodifiers.handle_binary_operation:promoted_typehas no 64-bit category, so when the other operand forces float/double promotion, agiga/thiccoperand (whose type isVAR_INT, with long-ness only inmodifiers) is fetched via(double)evaluate_expression_int(...)/(float)evaluate_expression_int(...), which narrows to 32 bits before the widening conversion.Follow-on from #282.