Problems with NaN (not a number)

  1. ‹ Older
  2. 5 years ago

    Michael D

    4 Nov 2015 Testers, Xojo Pro

    Is there a way to create a NaN constant?

    I recently ran into some OS X routines which expect CGRectNull constant, which is not a Nil pointer but rather a CGRect that is filled with {NaN,NaN,NaN,NaN}. I know MBS has a function to make it, but I was curious how to create that in pure Xojo code.

  3. Tim H

    4 Nov 2015 Portland, OR USA

    NaN is a particular 8-byte representation of a Double. Use an 8-byte memoryblock, set the appropriate byte values, and pull the DoubleValue out of it. (Or use 4 bytes and SingleValue if it expects a 4-byte representation.)

  4. Norman P

    4 Nov 2015 Xojo Inc, Xojo Pro Seeking work. npalardy@great-w...
    Edited 5 years ago

    NaN can be several different representations
    https://en.wikipedia.org/wiki/NaN

  5. Michael D

    4 Nov 2015 Testers, Xojo Pro

    Interesting : this page https://docs.oracle.com/cd/E19957-01/806-3568/ncg_math.html gives the hex values, and for a Single it looks like it's 7fc00000, for a double it's 7ff80000 00000000.

    Does Ctype work here? Can one say
    dim s as single = Ctype("NaN") ?

  6. Will S

    4 Nov 2015 Santa Cruz 
    Edited 5 years ago

    @Michael D expect CGRectNull constant

    From what I've found CGRectNull is [Inf, Inf, 0, 0].

    You can use CGRectIntersection with 2 disjoint rects and that's what I get back.

  7. Norman P

    4 Nov 2015 Xojo Inc, Xojo Pro Seeking work. npalardy@great-w...

    IEEE 754 NaNs are represented with the exponent field filled with ones (like infinity values), and some non-zero number in the significand (to make them distinct from infinity values); this representation allows the definition of multiple distinct NaN values, depending on which bits are set in the significand, but also on the value of the leading sign bit (not all applications are required to provide distinct semantics for those distinct NaN values).

    There can be MANY different NaN's :)

  8. Michel B

    4 Nov 2015 Testers, Xojo Pro

    @Norman P NaN can be several different representations
    https://en.wikipedia.org/wiki/NaN

    Very nice.

  9. Michael D

    4 Nov 2015 Testers, Xojo Pro

    @Will S From what I've found CGRectNull is [Inf, Inf, 0, 0].
    You can use CGRectIntersection with 2 disjoint rects and that's what I get back.

    Here's what I've found:

      const CGPoint CGPointZero = {0,0};
      const CGSize CGSizeZero = {0,0};
      const CGRect CGRectZero = {{0,0},{0,0}};
      const CGRect CGRectNull = {{NAN,NAN},{NAN,NAN}};
      const CGRect CGRectInfinite = {{INFINITY,INFINITY},{INFINITY,INFINITY}};
  10. Will S

    4 Nov 2015 Santa Cruz 
    Edited 5 years ago

    @Michael D Here's what I've found:

    const CGRect CGRectNull = {{NAN,NAN},{NAN,NAN}};

    Did you try CGRectIntersection? The docs say it returns CGRectNull and when I stringify such a result I get Inf, Inf, 0, 0

  11. Will S

    5 Nov 2015 Santa Cruz 
    Edited 5 years ago

    INF can be made like this, for Single

    m = new MemoryBlock(4)
    m.UInt32Value(0) = &h7F800000
    v = m.SingleValue(0)

    for Double

    m = new MemoryBlock(8)
    m.UInt64Value(0) = &h7FF0000000000000
    v = m.DoubleValue(0)

    but also v = 1 / 0 works. So this should make a CGRectNull in both 32 and 64 bit.

    dim r As CGRect
    r.x = 1 / 0
    r.y = 1 / 0
    r.w = 0
    r.h = 0
  12. Michael D

    5 Nov 2015 Testers, Xojo Pro
    Edited 5 years ago

    Will, it seems you may be correct?

      dim r as CGRectMBS = CGRectMBS.Null
      dim mb as MemoryBlock = r.Binary
      break

    In the debugger, mb has the bytes

    0000 807F 0000 807F 0000 0000 0000 0000

    I wonder if this is a documentation bug or something else? Perhaps the OS just looks at the 2 first Singles and if they are Inf it doesn't matter what the last two are?

  13. Will S

    5 Nov 2015 Santa Cruz 

    @Michael D I wonder if this is a documentation bug or something else?

    I couldn't find a definition in Apples docs or Xcode and turned to tweets like this
    https://twitter.com/MSch/status/271528930035507201
    Docs like this define a CGRectNull with NaNs but it's the Free Software Foundation, Inc. not Apple
    http://svn.gna.org/svn/gnustep/libs/opal/trunk/Source/OpalGraphics/CGGeometry.m

    Also it seems only one of x y needs to be INF to be considered a CGRectNull...

      dim r As CGRect
      r.x = 9
      r.y = 1 / 0
      r.w = 6
      r.h = 2
      
      declare function CGRectIsNull lib "Cocoa" (r As CGRect) As Boolean
      
      MsgBox "null " + Str(CGRectIsNull(r))     //True
  14. 3 years ago

    Robert W

    25 Jan 2017 Western Canada

    I realize that this is an old thread, but I recently had the need to detect when a math operation returns a bad value. I thought I'd seen an IsNaN function in the documentation, but apparently I'd been dreaming, or thinking of some other programming language. Anyway, I came up with the following, which is simpler than converting the result to string and looking for string patterns.

    Public Function IsNaN(x As Double) as Boolean
      return (x*0<>0)
    End Function
  15. Jean-Yves P

    25 Jan 2017 Testers, Xojo Pro Europe (France, Besançon)

    you can str(yournumber) and then search for "NAN" inside it's working.

  16. Christian S

    25 Jan 2017 Testers, Xojo Pro, XDC Speakers, Third Party Store Germany

    or isNanMBS function.

    Or simply if x <> x then as Nan will not compare to itself.

  17. Robert W

    26 Jan 2017 Western Canada

    @ChristianSchmitz Or simply if x <> x then as Nan will not compare to itself.

    I think that's effectively the same thing as what I posted. I was simply trying to point out that it's not necessary to convert the number into a string and then search for "NAN...."

  18. Michel B

    26 Jan 2017 Testers, Xojo Pro

    You can use isNumeric .

  19. Jean-Yves P

    26 Jan 2017 Testers, Xojo Pro Europe (France, Besançon)
    dim d as Double
    
    d = 0/0
    
    MsgBox str(d)
    
    if IsNumeric(d) then
    MsgBox "is numeric"
    end if

    "is numeric" is displayed on the screen ... so isnumeric thinks NAN is a numeric

  20. Michel B

    26 Jan 2017 Testers, Xojo Pro
    Edited 3 years ago

    Then use both isNumeric and

    if str(d) = "NaN" then
    //whatever
  21. Robert W

    26 Jan 2017 Western Canada

    I don't understand obsession of doing a string conversion. Why make it more complicated than necessary?

    I just ran a comparison between my IsNaN function, and Christian's suggestion of using "x<>x". Here are the results:

    Invalid
    Operation   x*0<>0   x<>x
    
    log(0)      True     False
    log(-1)     True     True 
    sqrt(-1)    True     True 
    1/0         True     False 
    -1/0        True     False 
    exp(1e40)   True     False 
    
    Valid
    Operation   x*0<>0   x<>x
    
    100         False    False 
    0/5         False    False 
    2+4         False    False 

    The x<>x comparison fails in many cases, apparently because it doesn't detect +inf or -inf

  22. Newer ›

or Sign Up to reply!