LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 04-20-2006, 11:58 PM   #1
daihard
Member
 
Registered: Jul 2003
Location: Lynnwood, WA
Distribution: Kubuntu 10.10
Posts: 912

Rep: Reputation: 32
Question C language: +/-Inf and NaN


Hi.

I'm wondering if I can get help here. I need to implement the following function in C.
Code:
double stringToDouble(const char *str);
The parameter, str, can be assumed to contain either a valid floating point number (e.g. 0.25, -3.44, etc) or one of the "non-number" entities; i.e. "Inf", "+Inf", "-Inf" or "NaN". The return value shall contain the converted value.

It's a piece of cake with GCC, which has atof() that does exactly that. For instance, atof("Inf") returns the double value equivalent of Inf (positive infinity). The problem is, as usual, Visual C++, where atof("Inf") returns 0.0.

Here is my rough draft. The question is, how can I assign values like +/-Inf and NaN to a double variable?
Code:
double stringToDouble(const char *str)
{
    double dVal;
#if defined(RDMS_LINUX)
    dVal = atof(str);
#else /* RDMS_WINDOWS */
    char  sign = 0;
    char *cp = str;
    if (*cp == '+' || *cp == '-')
        sign = *cp++;

    if (stricmp(cp, "inf") == 0) {
        if (!sign || sign == '+')
            dVal = /* assign +Inf */;
        else
            dVal = /* assign -Inf */;
    }
    else if (stricmp(cp, "nan") == 0)
        dVal = /* assign NaN */;
    else /* valid number */
        dVal = atof(cp);
#endif

    return dVal;
}
I need to replace the commented sections with actual code. How should I implement it?

TIA,
Dai
 
Old 04-21-2006, 01:07 AM   #2
addy86
Member
 
Registered: Nov 2004
Location: Germany
Distribution: Debian Testing
Posts: 332

Rep: Reputation: 31
#include <math.h>
Use INFINITY and NAN.
 
Old 04-21-2006, 10:34 AM   #3
daihard
Member
 
Registered: Jul 2003
Location: Lynnwood, WA
Distribution: Kubuntu 10.10
Posts: 912

Original Poster
Rep: Reputation: 32
Quote:
Originally Posted by addy86
#include <math.h>
Use INFINITY and NAN.
They are not included in <math.h> for Visual Studio .NET. Do you suggest that I take those values off of the GCC <math.h> and stick them into the Windows code? I could try that and see what happens.

[Update] Looks like I can use HUGE_VAL and -HUGE_VAL with Visual Studio .NET to represent +/-Inf. Now I need to figure out what can be used for NaN.

Last edited by daihard; 04-21-2006 at 10:47 AM.
 
Old 04-21-2006, 11:10 AM   #4
addy86
Member
 
Registered: Nov 2004
Location: Germany
Distribution: Debian Testing
Posts: 332

Rep: Reputation: 31
Do you get an error or did you just not find the #defines?

For NAN, you can use 0.0/0.0 (not sure about that one).
 
Old 04-21-2006, 11:14 AM   #5
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
Originally Posted by addy86
Do you get an error or did you just not find the #defines?

For NAN, you can use 0.0/0.0 (not sure about that one).
There are a good few things which are missing from windows math.h and has caused me problems before in doing cross platform code. I did have a link(can't see to find it at the mo) which shows the parts of c and c++ standard which are not in some headers.
 
Old 04-21-2006, 01:24 PM   #6
daihard
Member
 
Registered: Jul 2003
Location: Lynnwood, WA
Distribution: Kubuntu 10.10
Posts: 912

Original Poster
Rep: Reputation: 32
Quote:
Originally Posted by addy86
Do you get an error or did you just not find the #defines?

For NAN, you can use 0.0/0.0 (not sure about that one).
I just didn't find the defined macros. I searched both vc7/include and vc7/PlatformSDK/include, but to no avail.

Thanks for the suggestion on NaN. I will see if that works. If not, we may need to resort to a readme.txt saying you cannot specify NaN for float/double data due to the OS limitation.
 
Old 04-21-2006, 01:50 PM   #7
addy86
Member
 
Registered: Nov 2004
Location: Germany
Distribution: Debian Testing
Posts: 332

Rep: Reputation: 31
You can also use the following raw values:
+NAN float: 7fc00000
-NAN float: 7fc00000
+NAN double: 7ff8000000000000
-NAN double: 7ff8000000000000

+INF float: 7f800000
-INF float: 7f800000
+INF double: 7ff0000000000000
-INF double: 7ff0000000000000

Endianness is of no concern here.
 
Old 04-21-2006, 10:45 PM   #8
daihard
Member
 
Registered: Jul 2003
Location: Lynnwood, WA
Distribution: Kubuntu 10.10
Posts: 912

Original Poster
Rep: Reputation: 32
Quote:
Originally Posted by addy86
You can also use the following raw values:
+NAN float: 7fc00000
-NAN float: 7fc00000
+NAN double: 7ff8000000000000
-NAN double: 7ff8000000000000

+INF float: 7f800000
-INF float: 7f800000
+INF double: 7ff0000000000000
-INF double: 7ff0000000000000

Endianness is of no concern here.
Thanks for the info. I actually found the macros that defined those values inside vc7/PlatformSDK/include/AlphaOps.h. However, if I throw in the varible that holds, say, "+INF double", to _fpclass(), it does not return _FPCLASS_PINF as it should. Also, if I try to print out the content of the varible, it will print out what looks like a valid double value instead of +Inf.
Code:
double dVal = 0x7ff0000000000000;
printf("Value = %lf\n", dVal);
Code:
Value = 9218868437227405300.000000
 
Old 04-22-2006, 02:51 AM   #9
addy86
Member
 
Registered: Nov 2004
Location: Germany
Distribution: Debian Testing
Posts: 332

Rep: Reputation: 31
Well, if you do this:
double d = 5;
you will expect d to be 5.0, won't you? Instead try
Code:
unsigned long long raw = 0x7ff0000000000000;
double d = *( double* )&raw
By the way, I just noticed that the negative values are not different from the corresponding positive ones. This a mistake; change the '7' in the negative values to 'f'.
 
Old 04-24-2006, 11:34 AM   #10
daihard
Member
 
Registered: Jul 2003
Location: Lynnwood, WA
Distribution: Kubuntu 10.10
Posts: 912

Original Poster
Rep: Reputation: 32
Quote:
Originally Posted by addy86
Well, if you do this:
double d = 5;
you will expect d to be 5.0, won't you? Instead try
Code:
unsigned long long raw = 0x7ff0000000000000;
double d = *( double* )&raw
By the way, I just noticed that the negative values are not different from the corresponding positive ones. This a mistake; change the '7' in the negative values to 'f'.
DOH! My bad... thanks for the help. I've implemented +/-Inf and NaN that way and the code works on all platforms now!

Just goes to show how I must keep on learning.
 
Old 08-06-2009, 01:06 PM   #11
Xyro
LQ Newbie
 
Registered: Aug 2009
Location: Canada
Distribution: Ubuntu 9.04
Posts: 22

Rep: Reputation: 19
In gcc >=3.3:

__builtin_inf()
__builtin_nan("")
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Need Broadcom inf FinalStar Linux - Wireless Networking 1 08-09-2004 12:53 PM
why would sin(0). return nan? greenmuzz Programming 2 10-23-2003 06:03 AM
Using INF Files VxJasonxV Linux - Newbie 2 05-27-2003 10:36 PM
HCF INF File VxJasonxV Linux - Hardware 2 05-24-2003 08:48 PM
Is solution for control "NaN" and "Inf" in C/C++ gmitra Programming 2 09-19-2002 08:57 AM


All times are GMT -5. The time now is 02:01 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration