Putting an 'L' at the end of a literal gives different result

Hi

I have the following code:

1
2
3
4
5
6
7
    long double num1 =  10210.730;
    long double num2 = 10210.730L;

    char c1 =  fmodl (num1 * powl(10,4),10) + '0';
    char c2 =  fmodl (num2 * powl(10,4),10) + '0';

    cout << c1<< endl<<c2;;


Please could someone explain this difference?

Also, is there any other way of ensuring that I get the 'c2' result? I'm thinking of cases where I won't always be working with literals?

Thanks

Edit: Apologies, forgot to include the output!

1
2
9
0
Last edited on
rozick1 wrote:
long double num1 = 10210.730;

The type of the expression 10210.730 is double and its value is 10210.72999999999956344254314899444580078125 or, using the more compact hex notation, 0x9.f8aeb851eb85p+10

When you use it to initialize a long double variable, its value doesn't change (a valid double is also a valid long double)

rozick1 wrote:
long double num2 = 10210.730L;

The type of the expression 10210.730L is long double and its value, assuming GCC (it's different in e.g. MSVC), is 10210.730000000000000426325641456060111522674560546875 or 0x9.f8aeb851eb851ecp+10 in hex


after multiplication by powl(10,4) (aka 10000), you get

102107299.9999999956344254314899444580078125 aka 0xc.2c1147ffffffda8p+23
and
102107300.0000000000072759576141834259033203125 aka 0xc.2c1148000000001p+23

and there you should see how fmodl by 10 gives you 9 and 0 respectively.
Last edited on
What output are you receiving?

Since this appears to be C++ have you considered letting the compiler pick the proper overload of the fmod() and pow() functions?

1
2
3
4
5
    long double num1 =  10210.730;
    long double num2 = 10210.730L;

    char c1 =  fmod (num1 * pow(10,4),10) + '0';  // Notice using C++ fmod() instead of the C function fmodl().
    char c2 =  fmod (num2 * pow(10,4),10) + '0';


10210.730 is a double.
10210.730L is a long double.

10210.730 cannot be represented exactly as a floating point value. Making it a double and converting it to a long double loses precision compared to if you made it a long double to begin with.

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <iomanip>

int main()
{
	std::cout << std::setprecision(100);
	std::cout << "     double: " << 10210.730  << '\n';
	std::cout << "long double: " << 10210.730L << '\n';
}
     double: 10210.72999999999956344254314899444580078125
long double: 10210.730000000000000426325641456060111522674560546875
Topic archived. No new replies allowed.