Skip to content

Large finite floating-point results incorrectly expose integer-only scalar flags #1352

Description

@fglock

Summary

LooksLike v0.20.060 exposes a PerlOnJava numeric scalar-flag bug. A very
large finite floating-point value is represented as integer-only (IOK) rather
than floating-point (NOK), causing LooksLike::integer and
LooksLike::even to return true when standard Perl returns false.

CPAN evidence

  • Distribution: LooksLike v0.20.060
  • CPAN run: 20260910-101908-8428
  • Failure record: FAIL LooksLike::v0.20.060 LooksLike
  • Failing test: t/LooksLike.t, tests 167-168 and 718-719
  • PerlOnJava result: 847/851 assertions pass; 4 fail
  • System Perl result: the complete upstream suite passes, 1,113/1,113 tests
  • Environment: pure-Perl distribution; no XS, native library, display,
    network service, or platform prerequisite

The failure is reproducible on both the JVM and interpreter backends.

Minimal reproducer

use LooksLike;
use B ();

my $value = 4**4**4;
my $flags = B::svref_2object(\$value)->FLAGS;

printf "flags=%d IOK=%d NOK=%d integer=%d even=%d\\n",
    $flags,
    $flags & B::SVp_IOK(),
    $flags & B::SVp_NOK(),
    LooksLike::integer($value),
    LooksLike::even($value);

The value is displayed as 1.34078079299426e+154.

Expected behavior under standard Perl:

IOK=0 NOK!=0 integer=0 even=0

Observed on both PerlOnJava backends:

IOK!=0 NOK=0 integer=1 even=1

The same incorrect results appear for the negative value.

Root cause

LooksLike::integer and LooksLike::even inspect B::svref_2object(\$_)->FLAGS.
They use the integer fast path only when SVp_IOK is set and SVp_NOK is not
set; otherwise they validate the string representation. PerlOnJava evaluates
4**4**4 to the large floating-point value above but exposes it with
SVp_IOK set and SVp_NOK clear. The module therefore takes the integer fast
path, and the modulo operation reports the value as even.

This is not a LooksLike implementation error: the upstream implementation
and tests pass under system Perl. It is a shared scalar representation/flag
compatibility defect affecting both execution backends.

Impact

Pure-Perl code that uses B flags to distinguish integer and floating-point
values can misclassify large finite floats. This can affect numeric validators,
serialization decisions, deep comparison libraries, and other CPAN modules
that rely on Perl's scalar numeric state rather than only its printed value.

Expected fix

Preserve Perl-compatible numeric state for floating-point results whose
magnitude exceeds the representable native integer range. In particular,
large finite floating-point values must not acquire integer-only flags merely
because their binary value has no fractional component.

Add permanent project-owned regression coverage for the reproducer above,
including positive and negative values, and validate it under both the JVM and
interpreter backends after first verifying the expected behavior with system
Perl.

Related issues

Those issues concern adjacent scalar-typing/dual-value behavior. This issue
tracks the remaining incorrect IOK/NOK classification of large floating
point results and the resulting integer/even misclassification.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:backendJVM interpreter or execution-backend behaviorarea:cpan-portCPAN compatibility ports and providersarea:runtimeCore Perl runtime semanticsbugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions