Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

No floating point promotion to long double?

15 views
Skip to first unread message

restor

unread,
Apr 16, 2009, 7:15:29 PM4/16/09
to
Hi,
This is the question about the latest draft. Section "Floating point
promotion" (4.6) defines the promotion of a float to double. I found
it surprising that there is not a similar promotion from double to
long double. Is it deliberately so?

Regards,
&rzej

--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Pete Becker

unread,
Apr 18, 2009, 4:18:27 AM4/18/09
to
restor wrote:
>
> Hi,
> This is the question about the latest draft. Section "Floating point
> promotion" (4.6) defines the promotion of a float to double. I found
> it surprising that there is not a similar promotion from double to
> long double. Is it deliberately so?
>

Yes, it's deliberate, but that doesn't mean what you think it does.
Promotions are performed on the operands of various arithmetic
operators to bring the operands up to a minimum size. For integer
types this minimum size is int, and operands of type char, short, and
their signed/unsigned variants are promoted to int. Similarly, values
of type float are promoted to double.

For example:

float a = 1.0, b = 1.0;
float c = a + b;

Here, the values in a and b are promoted to double, the resulting
values are added, the sum is converted to float, and the result is
stored in c. If the three variables had type double, no promotions
would be done; the double values are simply added. And if they were
long double, again, no promotions; the long double values are simply
added.

There are conversions between the various types:

float a = 1.0;
double b = a; // float converted to double
long double c = a; // float converted to long double
c = b; // double converted to long double
b = c; // long double converted to double
a = c; // long double converted to float
a = b; // double converted to float

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)

wasti...@gmx.net

unread,
Apr 18, 2009, 4:17:44 AM4/18/09
to
restor wrote:
> Hi,
> This is the question about the latest draft. Section "Floating point
> promotion" (4.6) defines the promotion of a float to double. I found
> it surprising that there is not a similar promotion from double to
> long double. Is it deliberately so?

Yes, although I don't know the reason. But it mirrors integer
promotion: only conversion to int is a promotion; conversion of int to
long or long long is a conversion.

James Kanze

unread,
Apr 18, 2009, 4:15:28 AM4/18/09
to
On Apr 17, 1:15 am, restor <akrze...@interia.pl> wrote:

> This is the question about the latest draft. Section "Floating
> point promotion" (4.6) defines the promotion of a float to
> double. I found it surprising that there is not a similar
> promotion from double to long double. Is it deliberately so?

Yes. There's also no promotion of int to long.

Promotions are a special class of conversions, which are applied
when passing an argument to a function when there is no
parameter. (The argument matches the ...)

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Alf P. Steinbach

unread,
Apr 18, 2009, 4:14:31 AM4/18/09
to
* restor:

>
> This is the question about the latest draft. Section "Floating point
> promotion" (4.6) defines the promotion of a float to double. I found
> it surprising that there is not a similar promotion from double to
> long double. Is it deliberately so?

It seems that it was, but that there's trouble. :-)

First, note that what we in practice mean by "promotion" isn't
directly the promotion rules of §4, but rather the "usual arithmetic
conversions" of §5/9, which indeed do include promotion up to 'long
double'. Since it is a bit of a moutful to say "hey, x is
usual-arithmetic-converted to long double" in practice we just say
"hey, x is promoted to long double". It's useful to keep in mind that
in-practice terminology and standardeese are not always the same.

I searched the C++98 standard for "floating point promotion" and it
turns out that it's used directly in three places.

First, it's used in §4/1 as part of the definition of a /standard
conversion sequence/.

Second, it's used in §5.2.2/7 about promotion of arguments to variadic
routine (one with "..." argument specification). And for this it makes
eminent sense that there is no conversion up to 'long double'. Within
the routine you can rely on any actual argument of the inferior type
'float' having been converted up to 'double'. Similarly, since this
paragraph also invokes the integral promotions, you can rely on any
actual argument of one of the types 'char', 'signed char', 'unsigned
char', 'short' and 'unsigned short' having been promoted to 'int' or
'unsigned int', which are the same size. I.e., the macros for picking
up arguments can deal with a much reduced set of possible types.

Third, it's used in §13.3.3.1.1/3 about ranking of conversions, which
ranking (into one of the three categories Exact Match, Promotion or
Conversion) is used in §13.3.3.2/3 to rank implicit conversion
sequences for the purpose of overload resolution.

And this is problematic, because since 'double' -> 'long double' is
not a floating point promotion ranked as Promotion, but rather a
floating point conversion ranked as Conversion, it's no better than
e.g. 'double' -> 'int'.

Uh huh.

<code>
void foo( long double ) {}
void foo( int ) {}

void bar( double ) {}
void bar( int ) {}

int main()
{
foo( 3.14 ); // Ambiguous.
bar( 3.14f ); // OK.
}
</code>

I'd say this is a little bit surprising.

At least, it was surprising to me!

OK, checking the N2800 draft of C++0x...

Argh, it's the same in N2800.

I'm too lazy to download the latest draft, but, checking active issues...

Nope, no active issue on this in revision 62 of the list (it's dated
23rd March 2009).

Cheers, & surprised,

- Alf

--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! :-) Just going there is good. Linking
to it is even better! Thanks in advance!

James Kanze

unread,
Apr 19, 2009, 11:01:40 AM4/19/09
to
On Apr 18, 10:18 am, Pete Becker <p...@versatilecoding.com> wrote:
> restor wrote:

> > This is the question about the latest draft. Section
> > "Floating point promotion" (4.6) defines the promotion of a
> > float to double. I found it surprising that there is not a
> > similar promotion from double to long double. Is it
> > deliberately so?

> Yes, it's deliberate, but that doesn't mean what you think it
> does. Promotions are performed on the operands of various
> arithmetic operators to bring the operands up to a minimum
> size. For integer types this minimum size is int, and operands
> of type char, short, and their signed/unsigned variants are
> promoted to int. Similarly, values of type float are promoted
> to double.

> For example:

> float a = 1.0, b = 1.0;
> float c = a + b;

> Here, the values in a and b are promoted to double, the
> resulting values are added, the sum is converted to float, and
> the result is stored in c.

Not according to §5/9. As far as I know, floating point
promotion only occurs when passing a float to a vararg.

Of course, an implementation is allowed to do the calculations
with greater precision than float, if it wants. Some
implementations will do them as double, some as long double, and
some (VC++) will even use more precision than long double.

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


--

James Kanze

unread,
Apr 19, 2009, 1:46:22 PM4/19/09
to
On Apr 18, 10:14 am, "Alf P. Steinbach" <al...@start.no> wrote:
> * restor:

[...]


> I searched the C++98 standard for "floating point promotion"
> and it turns out that it's used directly in three places.

[...]


> Third, it's used in §13.3.3.1.1/3 about ranking of conversions, which
> ranking (into one of the three categories Exact Match, Promotion or
> Conversion) is used in §13.3.3.2/3 to rank implicit conversion
> sequences for the purpose of overload resolution.

> And this is problematic, because since 'double' -> 'long
> double' is not a floating point promotion ranked as Promotion,
> but rather a floating point conversion ranked as Conversion,
> it's no better than e.g. 'double' -> 'int'.

Good point. It's no different than the fact that short -> int
is a promotion, but short -> long isn't (and given a choice
between f( char ) and f( long ), called with a short, the call
is ambiguous), but it does lead to some surprises. (But then,
the fact that non lossy conversiond do not have precedence of
lossy conversions, period, least do some surprises.)

Note that this is probably why the constructor for
std::string::string( std::size_t, char ) isn't
std::string( char, std::size_t = 1 )---that would make
std::string( 3.14 ) convert 3.14 to a char, which is probably
not what the author intended.

As for considering it a defect, or changing it: that would break
C compatibility. And there seems to be a consensus in the
committee (more or less) that the basic arithmetic types should
behave as in C.

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


--

Pete Becker

unread,
Apr 19, 2009, 7:11:47 PM4/19/09
to
James Kanze wrote:
> On Apr 18, 10:18 am, Pete Becker <p...@versatilecoding.com> wrote:
>> restor wrote:
>
>>> This is the question about the latest draft. Section
>>> "Floating point promotion" (4.6) defines the promotion of a
>>> float to double. I found it surprising that there is not a
>>> similar promotion from double to long double. Is it
>>> deliberately so?
>
>> Yes, it's deliberate, but that doesn't mean what you think it
>> does. Promotions are performed on the operands of various
>> arithmetic operators to bring the operands up to a minimum
>> size. For integer types this minimum size is int, and operands
>> of type char, short, and their signed/unsigned variants are
>> promoted to int. Similarly, values of type float are promoted
>> to double.
>
>> For example:
>
>> float a = 1.0, b = 1.0;
>> float c = a + b;
>
>> Here, the values in a and b are promoted to double, the
>> resulting values are added, the sum is converted to float, and
>> the result is stored in c.
>
> Not according to §5/9. As far as I know, floating point
> promotion only occurs when passing a float to a vararg.
>

You're right: I muddled integral conversion with floating point conversions.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)

0 new messages