@@ -416,6 +416,150 @@ float mul_5_f32(float x) { return x * 5.0f; }
416416float sub_2_f32 (float x ) { return x - 2.0f ; }
417417float div_4_f32 (float x ) { return x / 4.0f ; }
418418
419+ // ============================================================================
420+ // LARGE INT64 + FLOAT CONSTANT TEST
421+ // ============================================================================
422+
423+ int test_int64_large_constant (const char * description , int size ) {
424+ printf ("\n%s\n" , description );
425+ printf ("======================================================================\n" );
426+
427+ // Create an int64 array of the requested size and fill with small increasing values.
428+ // Using small integers ensures integer -> floating conversions are not lossy for the
429+ // integer operand itself; the potential issue comes from the large floating constant.
430+ long long * input = malloc (size * sizeof (long long ));
431+ if (!input ) {
432+ printf (" ❌ FAILED: malloc failed\n" );
433+ return 0 ;
434+ }
435+ for (int i = 0 ; i < size ; i ++ ) {
436+ input [i ] = (long long )i ;
437+ }
438+
439+ // Compile expression. We use ME_AUTO so mixed-type rules are applied and the
440+ // compiler decides the result dtype.
441+ me_variable vars [] = {{"a" , ME_INT64 }};
442+ int err ;
443+ const char * expr_str = "(a + 90000.00001) + 1" ;
444+ me_expr * expr = me_compile (expr_str , vars , 1 , ME_AUTO , & err );
445+
446+ if (!expr ) {
447+ printf (" ❌ COMPILATION FAILED (error %d)\n" , err );
448+ free (input );
449+ return 0 ;
450+ }
451+
452+ me_dtype out_dtype = me_get_dtype (expr );
453+ printf (" Compiled expression: %s\n" , expr_str );
454+ printf (" Inferred output dtype: %d\n" , out_dtype );
455+
456+ int passed = 1 ;
457+ double max_diff = 0.0 ;
458+
459+ // Evaluate depending on inferred output dtype. The expression contains a
460+ // floating-point constant, so a floating output dtype is expected.
461+ const void * var_ptrs [] = {input };
462+
463+ if (out_dtype == ME_FLOAT64 ) {
464+ double * result = malloc (size * sizeof (double ));
465+ if (!result ) {
466+ printf (" ❌ FAILED: malloc for result failed\n" );
467+ me_free (expr );
468+ free (input );
469+ return 0 ;
470+ }
471+ me_eval (expr , var_ptrs , 1 , result , size );
472+
473+ // Compute expected values using double arithmetic.
474+ for (int i = 0 ; i < size ; i ++ ) {
475+ double expected = ((double )input [i ] + 90000.00001 ) + 1.0 ;
476+ double diff = fabs (result [i ] - expected );
477+ if (diff > max_diff ) max_diff = diff ;
478+ if (diff > 1e-9 ) passed = 0 ; // tight tolerance for this check
479+ }
480+
481+ printf (" Result (first 5): " );
482+ for (int i = 0 ; i < 5 && i < size ; i ++ ) printf ("%.9f " , result [i ]);
483+ printf ("...\n" );
484+
485+ printf (" Expected (first 5): " );
486+ for (int i = 0 ; i < 5 && i < size ; i ++ ) {
487+ double expected = ((double )input [i ] + 90000.00001 ) + 1.0 ;
488+ printf ("%.9f " , expected );
489+ }
490+ printf ("...\n" );
491+
492+ free (result );
493+
494+ } else if (out_dtype == ME_FLOAT32 ) {
495+ float * result = malloc (size * sizeof (float ));
496+ if (!result ) {
497+ printf (" ❌ FAILED: malloc for result failed\n" );
498+ me_free (expr );
499+ free (input );
500+ return 0 ;
501+ }
502+ me_eval (expr , var_ptrs , 1 , result , size );
503+
504+ for (int i = 0 ; i < size ; i ++ ) {
505+ float expected = (float )(((double )input [i ] + 90000.00001 ) + 1.0 );
506+ float diff = fabsf (result [i ] - expected );
507+ if (diff > max_diff ) max_diff = diff ;
508+ if (diff > 1e-5f ) passed = 0 ; // looser tolerance for float32
509+ }
510+
511+ printf (" Result (first 5): " );
512+ for (int i = 0 ; i < 5 && i < size ; i ++ ) printf ("%.7f " , result [i ]);
513+ printf ("...\n" );
514+
515+ printf (" Expected (first 5): " );
516+ for (int i = 0 ; i < 5 && i < size ; i ++ ) {
517+ float expected = (float )(((double )input [i ] + 90000.00001 ) + 1.0 );
518+ printf ("%.7f " , expected );
519+ }
520+ printf ("...\n" );
521+
522+ free (result );
523+
524+ } else {
525+ // Unexpected output dtype: try to evaluate into a double buffer and compare
526+ // raw integer or other outputs as a conservative fallback.
527+ printf (" ⚠️ Unexpected output dtype (%d). Attempting double evaluation for comparison.\n" , out_dtype );
528+ double * result = malloc (size * sizeof (double ));
529+ if (!result ) {
530+ printf (" ❌ FAILED: malloc for fallback result failed\n" );
531+ me_free (expr );
532+ free (input );
533+ return 0 ;
534+ }
535+ me_eval (expr , var_ptrs , 1 , result , size );
536+
537+ for (int i = 0 ; i < size ; i ++ ) {
538+ double expected = ((double )input [i ] + 90000.00001 ) + 1.0 ;
539+ double diff = fabs (result [i ] - expected );
540+ if (diff > max_diff ) max_diff = diff ;
541+ if (diff > 1e-9 ) passed = 0 ;
542+ }
543+
544+ free (result );
545+ }
546+
547+ me_free (expr );
548+ free (input );
549+
550+ if (passed ) {
551+ printf (" ✅ PASS\n" );
552+ } else {
553+ printf (" ❌ FAIL (max diff: %.12f)\n" , max_diff );
554+ }
555+
556+ // The caller expects this test to surface the reported problem; return the
557+ // actual pass/fail so it shows up in the overall summary. The external app
558+ // that reported the issue used this expression and observed incorrect
559+ // behaviour, so a failure here indicates the bug is present.
560+ return passed ;
561+ }
562+
419563// ============================================================================
420564// MAIN TEST RUNNER
421565// ============================================================================
@@ -556,6 +700,17 @@ int main() {
556700 total ++ ;
557701 if (test_scalar_constant ("Test 5.6: a / 4" , "a / 4" , div_4_f32 )) passed ++ ;
558702
703+ // ========================================================================
704+ // SECTION 6: LARGE INT64 + FLOAT CONSTANT (expected to fail)
705+ // ========================================================================
706+ printf ("\n\n========================================================================\n" );
707+ printf ("SECTION 6: LARGE INT64 + FLOAT CONSTANT\n" );
708+ printf ("========================================================================\n" );
709+
710+ total ++ ;
711+ if (test_int64_large_constant ("Test 6.1: (a + 90000.00001) + 1 where a is int64[1000]" ,
712+ 1000 )) passed ++ ;
713+
559714 // ========================================================================
560715 // FINAL SUMMARY
561716 // ========================================================================
0 commit comments