Discussion:
No difference between %f, %lf, and %Lf?
Nathan Sims
2011-06-03 16:28:54 UTC
Permalink
It would seem the only way I can display 8 significant digits after the decimal place using floats, doubles, or long doubles is to get the stringValue of an NSNumber (OSX 10.6.7, Xcode 3.2.6). I know internally the full precision is being used, but it appears there's no difference whatever between format specifiers %f, %lf, and %Lf. Or am I somehow using these incorrectly?

#import <Foundation/Foundation.h>
int main (int argc, const char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

float ftest = -175.12345678;
double dtest = -175.12345678;
long double ldtest = -175.12345678;
char fteststr[32], dteststr[32], ldteststr[32];

// try converting using C functions
sprintf(fteststr,"%f",ftest);
sprintf(dteststr,"%lf",dtest);
sprintf(ldteststr,"%Lf",ldtest);
NSLog(@"C values: Float: %f Double: %lf Long Double: %Lf",ftest,dtest,ldtest);
NSLog(@"C strings: Float: %s Double: %s Long Double: %s",fteststr,dteststr,ldteststr);

// try converting using NSNumbers
float f2test;
double d2test;
NSNumber *fNumb = [NSNumber numberWithFloat:ftest];
NSNumber *dNumb = [NSNumber numberWithDouble:dtest];
f2test = [fNumb floatValue];
d2test = [dNumb doubleValue];
NSString *sStr = [dNumb stringValue];
NSLog(@"NSNumber: Float: %f Double: %lf String: %@",ftest,dtest,sStr);

// try converting using NSStrings
NSString *fStr = [NSString stringWithFormat:@"%f",ftest];
NSString *dStr = [NSString stringWithFormat:@"%lf",dtest];
NSString *ldStr = [NSString stringWithFormat:@"%Lf",ldtest];
NSLog(@"NSString: Float: %@ Double: %@ String: %@",fStr,dStr,ldStr);

[pool drain];
return 0;
}

run
C values: Float: -175.123459 Double: -175.123457 Long Double: -175.123457
C strings: Float: -175.123459 Double: -175.123457 Long Double: -175.123457
NSNumber: Float: -175.123459 Double: -175.123457 String: -175.12345678 <--- the only correct result
NSString: Float: -175.123459 Double: -175.123457 String: -175.123457
Christiaan Hofman
2011-06-03 16:52:11 UTC
Permalink
Post by Nathan Sims
It would seem the only way I can display 8 significant digits after the decimal place using floats, doubles, or long doubles is to get the stringValue of an NSNumber (OSX 10.6.7, Xcode 3.2.6). I know internally the full precision is being used, but it appears there's no difference whatever between format specifiers %f, %lf, and %Lf. Or am I somehow using these incorrectly?
#import <Foundation/Foundation.h>
int main (int argc, const char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
float ftest = -175.12345678;
double dtest = -175.12345678;
long double ldtest = -175.12345678;
char fteststr[32], dteststr[32], ldteststr[32];
// try converting using C functions
sprintf(fteststr,"%f",ftest);
sprintf(dteststr,"%lf",dtest);
sprintf(ldteststr,"%Lf",ldtest);
// try converting using NSNumbers
float f2test;
double d2test;
NSNumber *fNumb = [NSNumber numberWithFloat:ftest];
NSNumber *dNumb = [NSNumber numberWithDouble:dtest];
f2test = [fNumb floatValue];
d2test = [dNumb doubleValue];
NSString *sStr = [dNumb stringValue];
// try converting using NSStrings
[pool drain];
return 0;
}
run
C values: Float: -175.123459 Double: -175.123457 Long Double: -175.123457
C strings: Float: -175.123459 Double: -175.123457 Long Double: -175.123457
NSNumber: Float: -175.123459 Double: -175.123457 String: -175.12345678 <--- the only correct result
NSString: Float: -175.123459 Double: -175.123457 String: -175.123457
The difference between %f, %lf, %Lf are about the size of the argument, not the representation as a string. For the representation such as number of decimals you have to provide flags and/or precision in the specifier IEEE printf specification.

Christiaan
Nathan Sims
2011-06-03 17:04:05 UTC
Permalink
Ah, yes, the precision specifier.
Thanks Christiaan.
Post by Christiaan Hofman
The difference between %f, %lf, %Lf are about the size of the argument, not the representation as a string. For the representation such as number of decimals you have to provide flags and/or precision in the specifier IEEE printf specification.
Kyle Sluder
2011-06-03 18:23:09 UTC
Permalink
Post by Christiaan Hofman
The difference between %f, %lf, %Lf are about the size of the argument, not the representation as a string. For the representation such as number of decimals you have to provide flags and/or precision in the specifier IEEE printf specification.
There is actually no difference at all between %f and %lf, as per the
printf(2) documentation. Because printf is a vararg function,
arguments are always promoted to doubles. Use %Lf for passing long
double arguments. But long double is wacky.

--Kyle Sluder

Loading...