3

I am dealing with a long double value that can have huge values.

At one time I have this number represented as NSString and I need to convert it to long double. I see that the only API I have is

[myString doubleValue];

I don't see a longDoubleValue.

Trying to convert this number using doubleValue...

long double x = (long double)[@"3765765765E933" doubleValue];

gives me inf and the number in question is a legit long double value, as these numbers can go up to 1.18973149535723176502E+4932.

How do I do that?

Duck
  • 34,902
  • 47
  • 248
  • 470
  • Does NSDecimalNumber provide you with the precision you needed? https://developer.apple.com/documentation/foundation/nsdecimalnumber#//apple_ref/occ/cl/NSDecimalNumber – chedabob Jul 07 '17 at 11:01
  • @chedabob NSDecimalNumber's exponent is limited to between -127 and 127, his number is much larger – mag_zbc Jul 07 '17 at 11:05

4 Answers4

2

Perhaps create a category on NSString yourself

NSArray *array = [myString componentsSeparatedByString:@"E"];
long double mantis = (long double)[array[0] doubleValue];
long double exponent = (long double)[array[1] doubleValue]; 
return mantis * exponent;

There will possibly be a loss of data though

edit
It would seem that long double on iOS is the same size as double. Maybe you will need a custom class to hold such large numbers.

Duck
  • 34,902
  • 47
  • 248
  • 470
mag_zbc
  • 6,801
  • 14
  • 40
  • 62
1

You could probably do:

long double s = strtold(myString.UTF8String, NULL);

but if sizeof(long double) is the same as sizeof(double) as mag_zbc says, you might still get Inf.

If you want to go the pow() route, there is powl() which takes and returns long doubles.

Wevah
  • 28,182
  • 7
  • 83
  • 72
  • `powl`????? GREAT! for some reason I have searched for a pow for long double and failed to found... so I am improving my answer. Thanks – Duck Jul 08 '17 at 11:48
0

In fact the answer of mag_zbc is almost there. The last line is incorrect.

Considering that the string has exponent, the correct is:

- (long double)longDoubleValue {
  NSArray *array = [string componentsSeparatedByString:@"E"];
  long double mantis = (long double)[array[0] doubleValue];  
  long double exponent = (long double)[array[1] doubleValue];
  long double multiplier = powl(10.0L, exponent);
  return mantis * multiplier;
}
Duck
  • 34,902
  • 47
  • 248
  • 470
0

You can do this using the C library sscanf function. Here is a sample Objective-C wrapper:

long double stringToLongDouble(NSString *str)
{
   long double result = 0.0L;
   int ret = sscanf(str.UTF8String, "%Lg", &result);
   if (ret != 1)
   {
      // Insert your own error handling here, using NSLog for demo
      NSLog(@"stringToLongDouble: could not parse '%@' as long double", str);
      return 0.0L;
   }
   return result;
}

The return from sscanf will be 1 if it succeeds. For possible error returns see the documentation (man 3 scanf in Terminal) and you need to decide how to handle these, the above example just does an NSLog.

Note: The size & precision of long double may vary by platform/OS version. The above has been tested with your value on El Capitan and iOS 10 (simulator only) using Xcode 8.

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86