Project

General

Profile

Bug #95

Problem with FLOAT64 arithmetic

Added by Alexey Morozov 8 months ago.

Status:
New
Priority:
Urgent
Category:
Compiler

Description

The problem can be reproduced with the following code (please pay attention to the comments):

MODULE TestFloat64;

IMPORT
    Commands;

    PROCEDURE Test*(ctx: Commands.Context);
    VAR
        days, hours, minutes, seconds: SIGNED32;
        timei: SIGNED64;
        time0, time1, time2, time3: FLOAT64;

        PROCEDURE Check(condition: BOOLEAN);
        BEGIN
            ASSERT(condition);
        FINALLY
        END Check;

    BEGIN
        days := 43403; hours := 15; minutes := 35; seconds := 55;

        timei := SIGNED64(days)*86400 + SIGNED64(hours)*3600 + SIGNED64(minutes)*60 + SIGNED64(seconds);
        time0 := timei;
        time1 := FLOAT64(days)*86400.0D0 + FLOAT64(hours)*3600.0D0 + FLOAT64(minutes)*60.0D0 + FLOAT64(seconds);
        time2 := FLOAT64(days)*86400 + FLOAT64(hours)*3600 + FLOAT64(minutes)*60 + FLOAT64(seconds);
        time3 := days*86400.0D0 + hours*3600.0D0 + minutes*60.0D0 + seconds;

        TRACE(timei);
        TRACE(time0, time1, time2, time3);
        ctx.out.String("timei="); ctx.out.Int(timei, 0); ctx.out.Ln;
        ctx.out.String("time0="); ctx.out.FloatFix(time0, 0, 15, 0); ctx.out.Ln;
        ctx.out.String("time1="); ctx.out.FloatFix(time1, 0, 15, 0); ctx.out.Ln;
        ctx.out.String("time2="); ctx.out.FloatFix(time2, 0, 15, 0); ctx.out.Ln;
        ctx.out.String("time3="); ctx.out.FloatFix(time3, 0, 15, 0); ctx.out.Ln;

        ctx.out.Update;

        Check(timei = 3750075355); (*OK*)
        Check(time0 = 3750075355); (*OK*)
        Check(time1 = 3750075355); (*!FAILS (least significant bit of mantissa is 1 instead of 0)*)
        Check(time2 = 3750075355); (*OK*)
        Check(time3 = 3750075355); (*!FAILS (completely wrong result)*)
    END Test;

END TestFloat64.

Also available in: Atom PDF