gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master 9f1c1542: Library (type.h): properly reading m


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 9f1c1542: Library (type.h): properly reading many digit numbers as double
Date: Wed, 26 Jan 2022 18:27:02 -0500 (EST)

branch: master
commit 9f1c1542cb18f9d9e3289f0c4ef91ff0433d8375
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Library (type.h): properly reading many digit numbers as double
    
    Until now, when a many-digit "small" number (like '330624.3918430004') is
    given to 'gal_type_string_to_number', it is mistakenly read as a 32-bit
    float number, not 64-bit. This causes problems like the example below (when
    reading FITS keywords that have values in a similar format). This
    'img.fits' can be any of the images that is initially downloaded in the
    general tutorial:
    
        $ astfits img.fits -h0 --keyvalue=TEXPTIME
        img.fits 330624
    
        $ astfits img.fits -h0 | grep TEXPTIME
        TEXPTIME=    330624.3918430004
    
    As you see, while the value is '330624.3918430004', the Fits program only
    prints the first 6 characters! The root cause of this problem is that
    'gal_type_string_to_number' is wrongly identifying this as a 32-bit
    floating point number!
    
    The cause of the problem was found in the wrong limit checks of
    'gal_type_string_to_number': previously if the number was smaller than the
    maximum float32 or larger than the minimum float32, the number of its
    digits was effectively ignored (there was an "or").
    
    With this commit, the condition check was fixed: we identify a number as
    float64 when the number of its meaningful digits is larger than 'FLT_DIG',
    or its absolute value is larger than the maximum float32 or smaller than
    the minimum float32 (more precision). This fixed the problem.
    
    This bug was first reported by Zohre Ghaffari and Pedram Ashofteh Ardakani
    helped in finding the solution.
    
    This fixes bug #61940.
---
 NEWS       | 8 ++++++--
 lib/fits.c | 2 +-
 lib/type.c | 6 +++---
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index 5bd53a4d..8a61905a 100644
--- a/NEWS
+++ b/NEWS
@@ -136,7 +136,7 @@ See the end of the file for license conditions.
               reported by Juan Antonio Fernández Ontiveros and Alejandro
               Lumbreras Calle.
   bug #61490: Extra columns in the metadata causes crash in plain-text
-              tables, found by Zohre Ghaffari.
+              tables, found by Zohreh Ghaffari.
   bug #61493: NoiseChisel's --checksn not showing pseudos equal to
               --snminarea (only larger ones), found by Raúl Infante-Sainz.
   bug #61584: When FITS file doesn't end with '.fits' and the output file
@@ -147,11 +147,15 @@ See the end of the file for license conditions.
   bug #61698: Mean operator of Arithmetic (for stacking many images) not
               returning NaN for blank regions when input is integer. This
               fix also resolves the same problem in the 'sum', 'std',
-              'median' and all 'sigclip-*' operators); reported by Zohre
+              'median' and all 'sigclip-*' operators); reported by Zohreh
               Ghaffari.
   bug #61740: WCSLIB conflicting with system's wide-character string (WCS)
               library in Gnulib checks for some systems; reported by Martin
               Guerrero Roncel.
+  bug #61940: Numbers with many decimals (like '330624.3918430004', common
+              in Julian dates for example) incorrectly read as float32
+              (thus loosing precision); reported by Zohreh Ghaffari, fixed
+              with help of Pedram Ashofteh Ardakani.
 
 
 
diff --git a/lib/fits.c b/lib/fits.c
index 40c48c79..d70f867d 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -1379,7 +1379,7 @@ gal_fits_key_read_from_ptr(fitsfile *fptr, gal_data_t 
*keysll,
            successfully read. */
         if(tmp->status==0 && typewasinvalid)
           {
-            /* If the string can be parsed as a number, then number will be
+            /* If the string can be parsed as a number, the number will be
                allocated and placed in 'numptr', otherwise, 'numptr' will
                be NULL. */
             numptr=gal_type_string_to_number(valueptr, &numtype);
diff --git a/lib/type.c b/lib/type.c
index 7f72d655..a6dd8ba0 100644
--- a/lib/type.c
+++ b/lib/type.c
@@ -639,10 +639,10 @@ gal_type_string_to_number(char *string, uint8_t *type)
 
       /* Calculate the number of decimal digits and decide if it the number
          should be a float or a double. */
-      if( lnz-fnz < FLT_DIG || ( d<FLT_MAX && d>FLT_MIN ) )
-        { f=d; ptr=&f; *type=GAL_TYPE_FLOAT32; }
-      else
+      if( lnz-fnz > FLT_DIG || abs(d)>FLT_MAX || abs(d)<FLT_MIN )
         {      ptr=&d; *type=GAL_TYPE_FLOAT64; }
+      else
+        { f=d; ptr=&f; *type=GAL_TYPE_FLOAT32; }
     }
 
   /* Allocate a one-element dataset, then copy the number into it. */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]