in reply to Re: Q: NaN again
in thread Q: NaN again

Problem in filtering of user input.
For example. User try to make bid at auction, and enter NaN in "price" field. All standart methods like: $price = sprintf("%.2f", $price); return me NaN But it not so bad. Really bad is:
if ($price > $user_money) { return "You have not enough money". }

Will fail for NaN. I found about 30 "nan holes" in my code after 5.8.4, and I suppose, I found not all of it.

P.S. Sorry for my bad english.

Replies are listed 'Best First'.
Re^3: Q: NaN again
by davorg (Chancellor) on Oct 19, 2006 at 12:14 UTC

    Then, as you say, your problem is with filtering user input. When you recieve input from a user, you need to check that it is a valid number and reject (or ignore) it if it isn't.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      I have a huge amount of old code. About ten megabytes. I can't check all. So, all I need to know - how to disable NaN autosupport in perl 5.8.4+ for amd64 :-)
Re^3: Q: NaN again
by syphilis (Archbishop) on Oct 19, 2006 at 12:32 UTC
    P.S. Sorry for my bad english

    That's ok ... no need to apologise for that. But it would really help if you could provide a complete (and simple) perl script that demonstrates one of the problems you are having.

    Support for NaN's does not exist in perl for all architectures/platforms. It would help us to know which architecture and platform you're running.

    Cheers,
    Rob
      web # perl -e '$a="nan"; print sprintf("%.2f",$a)' nan web # perl -v This is perl, v5.8.8 built for x86_64-linux ----- For Win32: This is perl, v5.8.4 built for MSWin32-x86-multi-thread perl -e "$a='nan'; print sprintf('%.2f',$a)" 0.00
        Yep - it's broken on Win32, and the nature of the breakage varies, depending upon which compiler (ie Visual Studio or MinGW) was used to build perl. I submitted a perlbug report about this (assigned a ticket number of 38779) a while back.

        But the example that you've provided fails in the same way, irrespective of whether perl was compiled with Visual Studio 6.0 or MinGW.

        I thought this had been fixed with Visual Studio 7.0 but I still I get (on my perl built with Visual Studio 7.0):
        F:\>perl -we "$a='nan'; print sprintf('%.2f',$a)" 0.00

        Let's face it ... handling of NaN's on Win32 is unreliable. I don't know how you can disable it. You could try re-compiling perl 5.8.8 with the following patch supplied by Jan Dubois in response to my perlbug report.
        --- pp.c.orig Wed Mar 22 19:35:45 2006 +++ pp.c Wed Mar 22 21:43:04 2006 @@ -1732,8 +1732,15 @@ } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETNO; + SETs(boolSV(left < right)); +#else dPOPnv; SETs(boolSV(TOPn < value)); +#endif RETURN; } } @@ -1808,8 +1815,15 @@ } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETNO; + SETs(boolSV(left > right)); +#else dPOPnv; SETs(boolSV(TOPn > value)); +#endif RETURN; } } @@ -1884,8 +1898,15 @@ } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETNO; + SETs(boolSV(left <= right)); +#else dPOPnv; SETs(boolSV(TOPn <= value)); +#endif RETURN; } } @@ -1960,8 +1981,15 @@ } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETNO; + SETs(boolSV(left >= right)); +#else dPOPnv; SETs(boolSV(TOPn >= value)); +#endif RETURN; } } @@ -2029,8 +2057,15 @@ } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETYES; + SETs(boolSV(left != right)); +#else dPOPnv; SETs(boolSV(TOPn != value)); +#endif RETURN; } } --- pp_hot.c.orig Wed Mar 22 19:35:45 2006 +++ pp_hot.c Wed Mar 22 21:42:38 2006 @@ -306,8 +306,15 @@ } #endif { +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + dPOPTOPnnrl; + if (Perl_isnan(left) || Perl_isnan(right)) + RETSETNO; + SETs(boolSV(left == right)); +#else dPOPnv; SETs(boolSV(TOPn == value)); +#endif RETURN; } } --- sv.c.orig Wed Mar 22 21:47:13 2006 +++ sv.c Wed Mar 22 21:31:27 2006 @@ -2134,6 +2134,13 @@ certainly cast into the IV range at IV_MAX, whereas the correc +t answer is the UV IV_MAX +1. Hence < ensures that dodgy boundar +y cases go to UV */ +#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan) + if (Perl_isnan(SvNVX(sv))) { + SvUV_set(sv, 0); + SvIsUV_on(sv); + } + else +#endif if (SvNVX(sv) < (NV)IV_MAX + 0.5) { SvIV_set(sv, I_V(SvNVX(sv))); if (SvNVX(sv) == (NV) SvIVX(sv) --- win32/win32.h.orig Wed Mar 22 19:35:49 2006 +++ win32/win32.h Wed Mar 22 21:35:54 2006 @@ -210,6 +210,11 @@ #define isnan _isnan +#if _MSC_VER < 1300 +/* VC6 has broken NaN semantics: NaN == NaN returns true instead of f +alse */ +#define NAN_COMPARE_BROKEN 1 +#endif + #endif /* _MSC_VER */ #ifdef __MINGW32__ /* Minimal Gnu-Win32 */

        I don't know if it will help. Good luck.

        Cheers,
        Rob