Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #84110 > unrolled thread

C++ (and some C) quiz questions

Started byJuha Nieminen <nospam@thanks.invalid>
First post2022-05-16 11:21 +0000
Last post2022-05-18 06:01 -0700
Articles 10 on this page of 30 — 8 participants

Back to article view | Back to comp.lang.c++


Contents

  C++ (and some C) quiz questions Juha Nieminen <nospam@thanks.invalid> - 2022-05-16 11:21 +0000
    Re: C++ (and some C) quiz questions Paavo Helde <eesnimi@osa.pri.ee> - 2022-05-16 17:35 +0300
      Re: C++ (and some C) quiz questions Juha Nieminen <nospam@thanks.invalid> - 2022-05-16 16:13 +0000
    Re: C++ (and some C) quiz questions Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-16 10:49 -0700
    Re: C++ (and some C) quiz questions Christian Gollwitzer <auriocus@gmx.de> - 2022-05-16 20:02 +0200
      Re: C++ (and some C) quiz questions "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-05-16 20:51 +0200
        Re: C++ (and some C) quiz questions Christian Gollwitzer <auriocus@gmx.de> - 2022-05-16 20:59 +0200
          Re: C++ (and some C) quiz questions Manfred <noname@add.invalid> - 2022-05-16 21:55 +0200
            Re: C++ (and some C) quiz questions Christian Gollwitzer <auriocus@gmx.de> - 2022-05-16 22:09 +0200
              Re: C++ (and some C) quiz questions Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-16 13:47 -0700
                Re: C++ (and some C) quiz questions Ben <ben.usenet@bsb.me.uk> - 2022-05-16 22:19 +0100
                  Re: C++ (and some C) quiz questions Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-16 14:52 -0700
                    Re: C++ (and some C) quiz questions Ben <ben.usenet@bsb.me.uk> - 2022-05-16 22:57 +0100
              Re: C++ (and some C) quiz questions Paavo Helde <eesnimi@osa.pri.ee> - 2022-05-17 00:54 +0300
                Re: C++ (and some C) quiz questions Ben <ben.usenet@bsb.me.uk> - 2022-05-17 00:34 +0100
                  Re: C++ (and some C) quiz questions Christian Gollwitzer <auriocus@gmx.de> - 2022-05-17 08:24 +0200
                    Re: C++ (and some C) quiz questions Juha Nieminen <nospam@thanks.invalid> - 2022-05-17 08:21 +0000
                      Re: C++ (and some C) quiz questions Ben <ben.usenet@bsb.me.uk> - 2022-05-17 11:06 +0100
          Re: C++ (and some C) quiz questions Juha Nieminen <nospam@thanks.invalid> - 2022-05-17 04:41 +0000
            Re: C++ (and some C) quiz questions Ben <ben.usenet@bsb.me.uk> - 2022-05-17 11:12 +0100
              Re: C++ (and some C) quiz questions Paavo Helde <eesnimi@osa.pri.ee> - 2022-05-17 14:37 +0300
                Re: C++ (and some C) quiz questions Ben <ben.usenet@bsb.me.uk> - 2022-05-17 14:31 +0100
              Re: C++ (and some C) quiz questions Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-05-17 04:53 -0700
                Re: C++ (and some C) quiz questions Juha Nieminen <nospam@thanks.invalid> - 2022-05-18 04:40 +0000
                  Re: C++ (and some C) quiz questions Manfred <noname@add.invalid> - 2022-05-18 13:29 +0200
                    Re: C++ (and some C) quiz questions Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-05-18 06:57 -0700
                      Re: C++ (and some C) quiz questions Paavo Helde <eesnimi@osa.pri.ee> - 2022-05-18 17:37 +0300
                        Re: C++ (and some C) quiz questions Juha Nieminen <nospam@thanks.invalid> - 2022-05-19 14:43 +0000
                        Re: C++ (and some C) quiz questions Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-05-19 08:21 -0700
                  Re: C++ (and some C) quiz questions Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-05-18 06:01 -0700

Page 2 of 2 — ← Prev page 1 [2]


#84145

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2022-05-17 14:37 +0300
Message-ID<t601d4$p09$1@dont-email.me>
In reply to#84144
17.05.2022 13:12 Ben kirjutas:
> Juha Nieminen <nospam@thanks.invalid> writes:
>>
>>      x = y * 0.1; // If x and y are long double, precision is lost
> 
>    7.4 Usual arithmetic conversions
> 
>    (1.2) — If either operand is of type long double, the other shall be
>            converted to long double.

Yes, and what happens when 0.1 is converted to long double (assuming 
long double is larger than double)? You will get a wrong value

0.100000000000000005551

instead of the intended more precise value

0.100000000000000000001



[toc] | [prev] | [next] | [standalone]


#84150

FromBen <ben.usenet@bsb.me.uk>
Date2022-05-17 14:31 +0100
Message-ID<87y1z0p9pc.fsf@bsb.me.uk>
In reply to#84145
Paavo Helde <eesnimi@osa.pri.ee> writes:

> 17.05.2022 13:12 Ben kirjutas:
>> Juha Nieminen <nospam@thanks.invalid> writes:
>>>
>>>      x = y * 0.1; // If x and y are long double, precision is lost
>>    7.4 Usual arithmetic conversions
>>    (1.2) — If either operand is of type long double, the other shall be
>>            converted to long double.
>
> Yes, and what happens when 0.1 is converted to long double (assuming
> long double is larger than double)?  You will get a wrong value
>
> 0.100000000000000005551
>
> instead of the intended more precise value
>
> 0.100000000000000000001

Yes, of course.  Sorry for the noise.  I was thinking about the more
general case, not the case of a literal.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#84146

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-05-17 04:53 -0700
Message-ID<86o7zw2x55.fsf@linuxsc.com>
In reply to#84144
Ben <ben.usenet@bsb.me.uk> writes:

> Juha Nieminen <nospam@thanks.invalid> writes:
>
>> Christian Gollwitzer <auriocus@gmx.de> wrote:
>>
>>>> Re #5, I guess that the problem with
>>>>
>>>>   long double value = 0.1;
>>>>
>>>> ... is that when `long double` doesn't have the same representation as
>>>> `double`, one may get a less precise value than with
>>>>
>>>>   long double value = 0.1L;
>>>>
>>>> Is that it?
>>>
>>> That's how I see it.  0.1 is a double constant and since 1/10 can't be
>>> represented exactly in binary (assuming binary floats), the value in
>>> "value" is not the closes approximation to 0.1 possible, which is 0.1L.
>>
>> It's easy to make such mistakes, and not just in variable initialization,
>> but also pretty much anywhere where a literal is used, like:
>>
>>     x = y * 0.1; // If x and y are long double, precision is lost
>
>   7.4 Usual arithmetic conversions
>
>   (1.2) ? If either operand is of type long double, the other shall be
>           converted to long double.

But that doesn't change the problem of potential loss of
precision, because the representation (and hence the particular
value) of the constant 0.1 is chosen before that value is
converted to long double.  The constant 0.1, being of type
double, doesn't have to have less precision than 0.1L, but
certainly it can.

[toc] | [prev] | [next] | [standalone]


#84157

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-05-18 04:40 +0000
Message-ID<t61tbu$1dmq$1@gioia.aioe.org>
In reply to#84146
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
> But that doesn't change the problem of potential loss of
> precision, because the representation (and hence the particular
> value) of the constant 0.1 is chosen before that value is
> converted to long double.  The constant 0.1, being of type
> double, doesn't have to have less precision than 0.1L, but
> certainly it can.

AFAIK no C/C++ compiler will second-guess the programmer and assume that
the literal was meant to be a long double literal. If you specify a
literal of type double, the compiler will assume you meant it (and will
just convert it to double without adding any precision to the resulting
value.)

With double vs. long double the loss in precision isn't extremely
drastic (although in some calculations it could accumulate to significant
proportions). However, people often make the mistake when they are using
some third-party multiple-precision libraries that support floating point
values of arbitrary size. If you are calculating with eg. 1024-bit
floating point, make sure you initialize them properly (ie. do not
initialize such a value with eg. the literal 0.1).

[toc] | [prev] | [next] | [standalone]


#84164

FromManfred <noname@add.invalid>
Date2022-05-18 13:29 +0200
Message-ID<t62lbd$12vc$1@gioia.aioe.org>
In reply to#84157
On 5/18/2022 6:40 AM, Juha Nieminen wrote:
> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>> But that doesn't change the problem of potential loss of
>> precision, because the representation (and hence the particular
>> value) of the constant 0.1 is chosen before that value is
>> converted to long double.  The constant 0.1, being of type
>> double, doesn't have to have less precision than 0.1L, but
>> certainly it can.
> 
> AFAIK no C/C++ compiler will second-guess the programmer and assume that
> the literal was meant to be a long double literal. If you specify a
> literal of type double, the compiler will assume you meant it (and will
> just convert it to double without adding any precision to the resulting
> value.)
> 
> With double vs. long double the loss in precision isn't extremely
> drastic (although in some calculations it could accumulate to significant
> proportions). However, people often make the mistake when they are using
> some third-party multiple-precision libraries that support floating point
> values of arbitrary size. If you are calculating with eg. 1024-bit
> floating point, make sure you initialize them properly (ie. do not
> initialize such a value with eg. the literal 0.1).

I believe Tim was referring to the fact that the standard does not 
mandate for long double to have more precision than double.

[toc] | [prev] | [next] | [standalone]


#84167

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-05-18 06:57 -0700
Message-ID<8635h72bap.fsf@linuxsc.com>
In reply to#84164
Manfred <noname@add.invalid> writes:

> On 5/18/2022 6:40 AM, Juha Nieminen wrote:
>
>> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>>
>>> But that doesn't change the problem of potential loss of
>>> precision, because the representation (and hence the particular
>>> value) of the constant 0.1 is chosen before that value is
>>> converted to long double.  The constant 0.1, being of type
>>> double, doesn't have to have less precision than 0.1L, but
>>> certainly it can.
>>
>> AFAIK no C/C++ compiler will second-guess the programmer and assume that
>> the literal was meant to be a long double literal.  If you specify a
>> literal of type double, the compiler will assume you meant it (and will
>> just convert it to double without adding any precision to the resulting
>> value.)
>>
>> With double vs. long double the loss in precision isn't extremely
>> drastic (although in some calculations it could accumulate to significant
>> proportions).  However, people often make the mistake when they are using
>> some third-party multiple-precision libraries that support floating point
>> values of arbitrary size.  If you are calculating with eg. 1024-bit
>> floating point, make sure you initialize them properly (ie. do not
>> initialize such a value with eg. the literal 0.1).
>
> I believe Tim was referring to the fact that the standard does not
> mandate for long double to have more precision than double.

That is one possibility, but I didn't mean just that.

Here is the original context:

    long double value = 0.1;

I'm not sure what C++ allows or doesn't allow for the value of
the literal 0.1.

For C, my understanding is that the current C standard allows the
constant 0.1 to be represented in the format, and precision, of a
long double even though its type is double.  (The rules for
floating constants in C has changed over time so I'm not sure if
that allowance might be different for earlier C standards.)

The next C standard apparently will be explicit on this point -
in the n2731 draft of the C standard, section 6.4.4.2 paragraph 6
says this in part:

    The values of floating constants may be represented in
    greater range and precision than that required by the type
    (determined by the suffix);  the types are not changed
    thereby.

[toc] | [prev] | [next] | [standalone]


#84170

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2022-05-18 17:37 +0300
Message-ID<t630am$4kh$1@dont-email.me>
In reply to#84167
18.05.2022 16:57 Tim Rentsch kirjutas:
> Manfred <noname@add.invalid> writes:
> 
>> On 5/18/2022 6:40 AM, Juha Nieminen wrote:
>>
>>> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>>>
>>>> But that doesn't change the problem of potential loss of
>>>> precision, because the representation (and hence the particular
>>>> value) of the constant 0.1 is chosen before that value is
>>>> converted to long double.  The constant 0.1, being of type
>>>> double, doesn't have to have less precision than 0.1L, but
>>>> certainly it can.
>>>
>>> AFAIK no C/C++ compiler will second-guess the programmer and assume that
>>> the literal was meant to be a long double literal.  If you specify a
>>> literal of type double, the compiler will assume you meant it (and will
>>> just convert it to double without adding any precision to the resulting
>>> value.)
>>>
>>> With double vs. long double the loss in precision isn't extremely
>>> drastic (although in some calculations it could accumulate to significant
>>> proportions).  However, people often make the mistake when they are using
>>> some third-party multiple-precision libraries that support floating point
>>> values of arbitrary size.  If you are calculating with eg. 1024-bit
>>> floating point, make sure you initialize them properly (ie. do not
>>> initialize such a value with eg. the literal 0.1).
>>
>> I believe Tim was referring to the fact that the standard does not
>> mandate for long double to have more precision than double.
> 
> That is one possibility, but I didn't mean just that.
> 
> Here is the original context:
> 
>      long double value = 0.1;
> 
> I'm not sure what C++ allows or doesn't allow for the value of
> the literal 0.1.
> 
> For C, my understanding is that the current C standard allows the
> constant 0.1 to be represented in the format, and precision, of a
> long double even though its type is double.  (The rules for
> floating constants in C has changed over time so I'm not sure if
> that allowance might be different for earlier C standards.)
> 
> The next C standard apparently will be explicit on this point -
> in the n2731 draft of the C standard, section 6.4.4.2 paragraph 6
> says this in part:
> 
>      The values of floating constants may be represented in
>      greater range and precision than that required by the type
>      (determined by the suffix);  the types are not changed
>      thereby.

Doesn't it just mean that in the program code, one can write the literal 
with more precision than needed, just in case the type may have more 
precision in another or future implementation?

const double pi = 3.141592653589793238462643383279502884197;


[toc] | [prev] | [next] | [standalone]


#84180

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-05-19 14:43 +0000
Message-ID<t65l30$1eic$1@gioia.aioe.org>
In reply to#84170
Paavo Helde <eesnimi@osa.pri.ee> wrote:
>> That is one possibility, but I didn't mean just that.
>> 
>> Here is the original context:
>> 
>>      long double value = 0.1;
>> 
>> I'm not sure what C++ allows or doesn't allow for the value of
>> the literal 0.1.
>> 
>> For C, my understanding is that the current C standard allows the
>> constant 0.1 to be represented in the format, and precision, of a
>> long double even though its type is double.  (The rules for
>> floating constants in C has changed over time so I'm not sure if
>> that allowance might be different for earlier C standards.)
>> 
>> The next C standard apparently will be explicit on this point -
>> in the n2731 draft of the C standard, section 6.4.4.2 paragraph 6
>> says this in part:
>> 
>>      The values of floating constants may be represented in
>>      greater range and precision than that required by the type
>>      (determined by the suffix);  the types are not changed
>>      thereby.
> 
> Doesn't it just mean that in the program code, one can write the literal 
> with more precision than needed, just in case the type may have more 
> precision in another or future implementation?
> 
> const double pi = 3.141592653589793238462643383279502884197;

There may indeed be a bit of confusion in concepts at play here. After all,
there are three stages of compilation at which precision of a floating point
literal plays a role: In the ascii representation of the value in the source
code, the internal value that the compiler converts that ascii representation
to, and the value that ends up in the executable binary. All three may (in
a sense, when it comes to the first form) use different precisions.

I really think that something like a programming language standard should
be clearer and more unambiguous about things like this (unless, perhaps,
the standard specifies somewhere else precisely what it means by
"values" being "represented".)

[toc] | [prev] | [next] | [standalone]


#84185

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-05-19 08:21 -0700
Message-ID<86y1yx1rb0.fsf@linuxsc.com>
In reply to#84170
Paavo Helde <eesnimi@osa.pri.ee> writes:

> 18.05.2022 16:57 Tim Rentsch kirjutas:
>
>> Manfred <noname@add.invalid> writes:
>>
>>> On 5/18/2022 6:40 AM, Juha Nieminen wrote:
>>>
>>>> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>>>>
>>>>> But that doesn't change the problem of potential loss of
>>>>> precision, because the representation (and hence the particular
>>>>> value) of the constant 0.1 is chosen before that value is
>>>>> converted to long double.  The constant 0.1, being of type
>>>>> double, doesn't have to have less precision than 0.1L, but
>>>>> certainly it can.
>>>>
>>>> AFAIK no C/C++ compiler will second-guess the programmer and assume that
>>>> the literal was meant to be a long double literal.  If you specify a
>>>> literal of type double, the compiler will assume you meant it (and will
>>>> just convert it to double without adding any precision to the resulting
>>>> value.)
>>>>
>>>> With double vs. long double the loss in precision isn't extremely
>>>> drastic (although in some calculations it could accumulate to significant
>>>> proportions).  However, people often make the mistake when they are using
>>>> some third-party multiple-precision libraries that support floating point
>>>> values of arbitrary size.  If you are calculating with eg. 1024-bit
>>>> floating point, make sure you initialize them properly (ie. do not
>>>> initialize such a value with eg. the literal 0.1).
>>>
>>> I believe Tim was referring to the fact that the standard does not
>>> mandate for long double to have more precision than double.
>>
>> That is one possibility, but I didn't mean just that.
>>
>> Here is the original context:
>>
>>      long double value = 0.1;
>>
>> I'm not sure what C++ allows or doesn't allow for the value of
>> the literal 0.1.
>>
>> For C, my understanding is that the current C standard allows the
>> constant 0.1 to be represented in the format, and precision, of a
>> long double even though its type is double.  (The rules for
>> floating constants in C has changed over time so I'm not sure if
>> that allowance might be different for earlier C standards.)
>>
>> The next C standard apparently will be explicit on this point -
>> in the n2731 draft of the C standard, section 6.4.4.2 paragraph 6
>> says this in part:
>>
>>      The values of floating constants may be represented in
>>      greater range and precision than that required by the type
>>      (determined by the suffix);  the types are not changed
>>      thereby.
>
> Doesn't it just mean that in the program code, one can write the
> literal with more precision than needed, just in case the type may
> have more precision in another or future implementation?
>
> const double pi = 3.141592653589793238462643383279502884197;

The short answer to this question is no.  That seems obvious to
me, but let me try to give a more complete explanation.

When talking about floating point, the C standard uses the terms
range and precision in relation to aspects of elements in the
abstract machine.  (There are separate notions of "precision"
that pertain to integer types or to the *printf() functions, but
these uses do not concern us here.)

In contrast, a floating constant occurs in program source and is
just a sequence of characters.  A floating constant has a source
form but does not have a range or precision, as the C standard
uses those terms.

The word "type" is used both to mean a compile-time notion that
is manipulated during compilation and to describe an internal
format that occurs inside the abstract machine at run time.  In
many cases these two notions are used interchangeably, but they
aren't quite the same, and pointedly so in the case of floating
point.  For example, in n1570 (a C11 draft), 6.3.1.8 paragraph 2
says this:

    The values of floating operands and of the results of
    floating expressions may be represented in greater range and
    precision than that required by the type;  the types are not
    changed thereby.

This sentence illustrates the distinction between "type" as a
compile-time notion and a run-time internal format, which may
be different than the internal format of the compile-time type.

Floating constants have a compile-time type (which is determined
by their suffix, or lack thereof).  However the type does not
necessarily determine the internal format used to represent the
constant.  Again from n1570, 6.4.4.2 paragraph 5 says in its
last sentence:

    All floating constants of the same source form(75) shall
    convert to the same internal format with the same value.

The footnote numbered 75 gives clarifying examples:

    1.23, 1.230, 123e-2, 123e-02, and 1.23L are all different
    source forms and thus need not convert to the same internal
    format and value.

After reading the above explanation I hope it is clear that the
excerpt from n2731 refers to what internal format is used, and
does not refer to any aspect of the source form (except of course
indirectly because constants having the same source form must use
the same internal format and have the same value).

Does that make more sense now?

[toc] | [prev] | [next] | [standalone]


#84166

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-05-18 06:01 -0700
Message-ID<867d6j2dwu.fsf@linuxsc.com>
In reply to#84157
Juha Nieminen <nospam@thanks.invalid> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>
>> But that doesn't change the problem of potential loss of
>> precision, because the representation (and hence the particular
>> value) of the constant 0.1 is chosen before that value is
>> converted to long double.  The constant 0.1, being of type
>> double, doesn't have to have less precision than 0.1L, but
>> certainly it can.
>
> AFAIK no C/C++ compiler will second-guess the programmer and
> assume that the literal was meant to be a long double literal.  If
> you specify a literal of type double, the compiler will assume you
> meant it [...]

My statement is not about what compilers do but only about what
the respective standards allow.

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.c++


csiph-web