Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What kind should be my variable in order to support small numbers?

Tags:

objective-c

I have this code:

return 1.0 / (1 + exp(-x));

It is used to calculate the value of a sigmoid function for a given x. The problem is that it always returns 1.00000

I started going through the code to see where it fails and I got to this:

long double expV = exp(-x);
long double btm = (1 + expV);
long double calc = 1.0 / btw;

Now the values of the variables are:

(long double) expV = 3.0356148105583944943E-165
(long double) btm = 1
(long double) calc = 1

So my question is how to fix the problem should I use another type for the variables or should I change something in the code?

Update btm should be of value: 1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030356148105583944943 as WolframAplha said

The value of x is 1 and x is of type double not long double. I change it to long double and report.

like image 285
Marti Markov Avatar asked Dec 03 '25 21:12

Marti Markov


2 Answers

The problem here is that the precision of the long double isn't sufficient to cope with such a small addition (in the case of btm). The '1' outweighs the tiny expV and thus, within the precision of the long double, btm is merely 1.

In answer to your question, your code is fine: logically there is nothing wrong, you just need a more precise data type. Unfortunately, Objective-C doesn't provide one (some discussion here about arbitrary precision in Objective-C). However, if you're willing to go a little further afield, the GNU MP library (and others) will be able to help you out with arbitrary precision mathematics. Of course, arbitrary precision maths comes at a performance cost - there's no such thing as a free lunch, sadly.

like image 84
Ephemera Avatar answered Dec 05 '25 10:12

Ephemera


EDIT: Sorry, the exponent support in NSDecimalNumber is from -128 to 127 so wouldnt work in this particular case but otherwise it is good for fixed point arithmetic calculations

PREVIOUS ANSWER: NSDecimalNumber

NSDecimalNumber* expV = [NSDecimalNumber decimalNumberWithMantissa:3.0356148105583944943
                                          exponent:-165
                                          isNegative:NO];
NSDecimalNumber* k = [NSDecimalNumber decimalNumberWithString:@"2.0"];

NSDecimalNumber* btm = [expV decimalNumberByAdding:k];

NSDecimalNumber* calc = [k decimalNumberByDividingBy:btm];

may not be the most elegant way to do it :/

like image 38
Abhineet Prasad Avatar answered Dec 05 '25 11:12

Abhineet Prasad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!