long double in gcc implementations

J

jacob navia

Skarmander a écrit :

[snip]
[Jacob navia wrote]
A more precise floating type, besides, is mentioned in the C standard.
In the C standard it is specified in 6.11:

< quote >
6.11 Future language directions
6.11.1 Floating types
1 Future standardization may include additional floating-point types,
including those with greater range, precision, or both than long double.
< end quote >

Lcc-win32 follows this directive. The floating point type "qfloat",
conforms precisely to the usage of other floating point types.
[Skarmander wrote]
Whoa there. This is *not* a directive, and not directed at you in any
case. You are indeed free to implement nonstandard floating point types,
but that is not a result of the section you quoted. That merely says
that the standards committee may add more types in the future. That
implementations may provide extensions so long as this doesn't affect
conforming programs is mentioned elsewhere.

Excuse me but "Future directions" means what it says: the directions
the comitee wants to follow in future issues of the standard.

Besides, in the paragraph J: "Common extensions" we have:

< quote >
J.5.6 Other arithmetic types
1 Additional arithmetic types, such as _ _int128 or double double, and
their appropriate conversions are defined (6.2.5, 6.3.1). Additional
floating types may have more range or precision than long double, may be
used for evaluating expressions of other floating types, and may be used
to define float_t or double_t.

< end quote >

This means that qfloat is included in the "common extensions" feature of
the standard, that explicitely mentions things that are not standard
but sufficiently common to be OKed, even if this is not normative.

All this extensions can be disabled when invoking the compiler with
-ansic
flag.
 
S

Skarmander

jacob said:
Skarmander a écrit :

[snip]
[Jacob navia wrote]
A more precise floating type, besides, is mentioned in the C standard.
In the C standard it is specified in 6.11:

< quote >
6.11 Future language directions
6.11.1 Floating types
1 Future standardization may include additional floating-point types,
including those with greater range, precision, or both than long double.
< end quote >

Lcc-win32 follows this directive. The floating point type "qfloat",
conforms precisely to the usage of other floating point types.
[Skarmander wrote]
Whoa there. This is *not* a directive, and not directed at you in any
case. You are indeed free to implement nonstandard floating point
types, but that is not a result of the section you quoted. That merely
says that the standards committee may add more types in the future.
That implementations may provide extensions so long as this doesn't
affect conforming programs is mentioned elsewhere.

Excuse me but "Future directions" means what it says: the directions
the comitee wants to follow in future issues of the standard.
Exactly, and you are not the committee. Section 6.11 is not any sort of hint
or instruction to implementers to extend the language. Your remark about
"following" this directive made no sense.
Besides, in the paragraph J: "Common extensions" we have:

< quote >
J.5.6 Other arithmetic types
1 Additional arithmetic types, such as _ _int128 or double double, and
their appropriate conversions are defined (6.2.5, 6.3.1). Additional
floating types may have more range or precision than long double, may be
used for evaluating expressions of other floating types, and may be used
to define float_t or double_t.

< end quote >

This means that qfloat is included in the "common extensions" feature of
the standard, that explicitely mentions things that are not standard
but sufficiently common to be OKed, even if this is not normative.
I explicitly said implementations are allowed to provide such extensions, as
does the standard. This is not contested. I merely pointed out that the
section you quoted earlier is irrelevant to the specific point you were
making - and that is all.
All this extensions can be disabled when invoking the compiler with
-ansic
flag.

A step up from many other compilers, for sure.

S.
 
G

Gordon Burditt

lcc-win32 has outrun any casual connection to C.)
In the C standard it is specified in 6.11:

< quote >
6.11 Future language directions
6.11.1 Floating types
1 Future standardization may include additional floating-point types,
including those with greater range, precision, or both than long double.
< end quote >

Lcc-win32 follows this directive. The floating point type "qfloat",
conforms precisely to the usage of other floating point types.

Lcc-win32 specializes in providing the highest support that C can
provide to mathematical users. Together with the qfloat type
an int128 type is provided.

There is nothing in the C standards that specifically
forbids adding extended mathematical types or new kind
of numbers. In general, extensions are NOT forbidden.

Does the following compile?

int foo(void)
{
float qfloat, class, new, delete;

/* ... bunch of stuff that uses these variables */
return 0;
}

If 'qfloat' is a built-in typedef or something similar, you've
In the C standard we read in Paragraph 4: Conformance:

< quote >
A conforming implementation may have extensions (including additional
library functions), provided they do not alter the behavior of any
strictly conforming program.
< end quote >
That includes namespace issues over the name 'qfloat'.
This is clear. My implementation remains conforming. If you do not
want to use qfloats nobody forces you to.

Gordon L. Burditt
 
T

Tom St Denis

jacob said:
Lcc-win32 follows this directive. The floating point type "qfloat",
conforms precisely to the usage of other floating point types.

Lcc-win32 specializes in providing the highest support that C can
provide to mathematical users. Together with the qfloat type
an int128 type is provided.

The problem I have with this is that C++ addresses this fairly well.
If you really want to give people large floats write a C++ library
using operation overloading. That way people are not tied to your
compiler platform and can best use the technology.

Tom
 
L

lcw1964

jacob said:
Just use it. I think you will like it because there are features
like 100 digit precision floats that you will be pressed to find
elsewhere. The math libraries are very extended, as you have noticed.

I am just interested in writing some math code for myself and higher
precision, if it gives consistently valid results and I can learn to
use the provided libraries to advantage. This will take some learning
and experimenting. I am not interested in portability, though I do
respect for the serious developer that that is desireable.

Monsieur Navia, I thank you for directing me to your product and I will
experiment with it at my leisure. Since I am not programming space
shuttle navigation systems I don't need mission critical perfection,
and just want to learn something new. As I am not programming for
commercial purposes I will not purchase a license and will take your
referral to your product as free advice, and will give you the benefit
of the doubt as to your intentions.

However, sir, if there is a legitimate complaint here in the group that
you are not totally transparent in disclosing the features and
limitations of your product, I would encourage you to look at that
honestly. But I know it is hard to take a humble and self-reflective
stance when one's critics imbue feedback with ad hominem personal
attacks. I stopped reading the ranting of one of your critics in this
thread when he demeaned himself to calling you a "stupid man". I think
it is possible that you may have very different ideas than many
professional programmers about what is or is not desireable in a
software development product, and you are entitled to your view and
your own market niche. But getting personal seems a little excessive.
However, like I said, if this acrimony emanates from legitimate
misgivings about what your product offers vis-a-vis the other
alternatives out there, it may be wise to accept that feedback and try
to disentangle the personal attacks from the worthwhile advice.

This all said, I must admit to a tinge of resentment myself by the
implication in some posts in this thread that I could be a naive "mark"
about to be sold Florida swamp land from the consummate confidence man.
Words like "bush-league", "hobbyist", "inexperience", etc., connote
only my amateur status, not stupidity. Heck, I write simple C programs
for fun, so I obviously must have an IQ about 80 at least, so I deserve
some credit. Thanks, but no thanks, for the warning, I am a big boy,
and can take care of myself.

Mr. Navia, if I have any questions about your product I will write you.
As for the rest of you, can you move the flame war to another thread
and get back to helping me out by trying to answer my original
question?

Les
 
J

jacob navia

Richard Heathfield a écrit :
jacob navia said:




"Genius programmers like you should not use lcc-win32." - Jacob Navia.

Where do I insult someone with that remark?
I advise you not to use a compiler system that
you tell again and again that is bad.
"Excuse me sir. Should I speak to you as "your holiness" maybe ?" - Jacob
Navia.

Yes, I was treating you of "Richard" and you
protested (I think you thought that "Richard" is an insult:)

Bewildered I asked you back how should I treat you. Well
I have settled for "Heathfield". I hope you do not
think that is an insult, Heathfield.
"Your language (hopes to cover his silly ass, etc) just shows your anal
fixation... Go to a doctor man." - Jacob Navia.

I was complaining about bad manners. I definitely do not
like people that swear and put "ass" in every sentence.
Note that there are no insults in my post.
"Please turn on your brain before complaining..." - Jacob Navia.

That is an advise Heathfield. Nowhere there is an insult.

An advise that with good manners discussions are less emotional
and more to the point. Flame fests are so boring.

You do not like lcc-win32?

You are not the only one. Please keep cool and expose your views.

Explain why providing features like 100 digits precision is
bad for the user.

Go ahead.

jacob
 
S

Skarmander

jacob navia wrote:
An advise that with good manners discussions are less emotional
and more to the point. Flame fests are so boring.
Then don't fan the flames.
You do not like lcc-win32?

You are not the only one. Please keep cool and expose your views.

Explain why providing features like 100 digits precision is
bad for the user.

Go ahead.
Plus ça change, plus c'est la même chose.

You *know* this is not what he was saying or even implying, so why do you
insist on attributing it to him? I can only imagine that you *like*
pointless discussions.

Knock yourself out.

S.
 
R

Richard Heathfield

jacob navia said:
Richard Heathfield a écrit :

Where do I insult someone with that remark?

Either it's sarcastic or it's not. If it's sarcastic, it's a personal
attack. If it's not sarcastic, you are advising intelligent programmers not
to use your product. Which is it?
Yes, I was treating you of "Richard" and you
protested (I think you thought that "Richard" is an insult:)

You are confused. The comment I quoted was not addressed to me. I am not
your only target by any means.
I was complaining about bad manners.

It is bad manners to use comp.lang.c for constant plugging of your
commercial product. So please stop doing it.

You do not like lcc-win32?

I have no idea. I've never, ever tried it. And because of your appalling
behaviour here in comp.lang.c, it is unlikely that I ever will.
Explain why providing features like 100 digits precision is
bad for the user.

I never claimed it was. Learn to read before responding.
 
F

Flash Gordon

Gordon Burditt wrote:

Javob wrote the material quoted by Gordon.

Gordon, please start providing attributions. Consider this yet another
complaint on the long list of complaints about you not providing
attributions.
Does the following compile?

#include <math.h>
#include <float.h>
#include <stdlib.h>
#include <stdio.h>
/* Add other standard headers to taste. After all, the standard headers
are not allowed to invade user namespace either */
int foo(void)
{
float qfloat, class, new, delete;

/* ... bunch of stuff that uses these variables */
return 0;
}

If 'qfloat' is a built-in typedef or something similar, you've
got problems. If, on the other hand, you have to include <qfloat.h>
in order to use the qfloat type, you're OK.

Agreed. However, qfloat would still not be topical here. Although I
would have said implementing it as __qfloat would have been better.
That includes namespace issues over the name 'qfloat'.

Only if it does not invade user namespace.
 
E

Eric Sosman

jacob said:
Eric Sosman a écrit :

I answer to you Eric because there were no insults in
your post. Others, I will just ignore.

If only you'd be as good as your word -- but you broke
it less than twenty minutes later, going by the time stamps
on my news server.
Concerning the argument that "this group is about standard c"

... an argument I did not make ...
I have countless times repeated that there is NO LEGAL BASIS
for that since this group has no chart.

"Charter." No, comp.lang.c traces its origins to the days
before newsgroup charters existed, as you quite well know. The
lack of charter is not an indication that the group is a free-
for-all in which all things are topical; *all* newsgroups from
those early days were created without charters. That doesn't
mean they were created without purpose.
This is Usenet and
I can express my opinion about this or that as I wish without
anybody having to get upset.

This is Usenet, and others are free to express their opinions
about lcc-win32, Jacob Navia, the relative merits of Steinway and
Yamaha pianos, and equally relevant topics.
> As you may have noticed, my posts do not
> contain insults or personal attacks to anyone, not even with
> people that have a long record of polemic.

Your non-polemical, non-attacking posts have in the past
employed a rather vigorous vocabulary ...
 
M

Michael Mair

Tom said:
And to think I remember a time when "lcc" referred to an ANSI-C
compiler...

It still is (*) -- appending the pejorative "win32" to a certain branch
somehow rotted said branch's "C-ness". Go figure.

Not really serious
Michael

(*) lcc indeed is still a C compiler; for example, Matlab comes with
lcc as mex compiler (if you do not have something better).
 
K

Keith Thompson

Eric Sosman said:
Fine. Use it good health. However, keep in mind that
this compiler (if we are to believe Jacob's description) is
not a C compiler, at least, not a C compiler in its usual
mode of operation. It's some kind of C-plus-extra-goodies
compiler, and if you get hooked on the goodies you may find
that your code won't run on any other systems.
[...]

To be fair, many, perhaps most, C compilers are non-conforming in
their default mode, and many, perhaps most, C compilers offer
extensions. Consider gcc, for example. The C standard specifically
allows extensions as long as they don't break any strictly conforming
code; extensions that do break strictly conforming code are allowed as
long as there's a mode in which those extensions are disabled.

My understanding is that lcc-win32 provides command-line options that
disable its extensions and cause it to operate as a conforming C
compiler, either for C90 or for C99. I don't know how good its C99
conformance is.

In effect, a compiler in conforming mode and the same compiler in
another mode that provides non-standard extensions are two different
implementations, one conforming and one not. The C standard logically
has nothing to say about non-conforming implementations, other than
that they're non-conforming.

Since this newsgroup discusses standard C, we tend to place more
emphasis on standard conformance and portability than might be
necessary in other contexts. There's definitely a price to be paid
for whatever benefits you get from using non-portable extensions.
Only you can decide whether it's worth the price.

In my opinion, it's very important, at the very least, to be aware of
which features are defined by the standard and which are
compiler-specific extensions. If you find some lcc-win32 extension
useful, go ahead and use it -- but be aware that other compilers are
unlikely to support it, and you won't be able to compile your code on
any platform that lcc-win32 doesn't support. jacob tends to gloss
over this fact.

There are a number of C-based languages. One of them is C++; it has
several newsgroups devoted to it, including comp.lang.c++. Another is
Objective C; it has its own newsgroup, comp.lang.objective-c. And
another is the extended C-like language supported by lcc-win32 in its
non-conforming mode; feel free to discuss that in comp.compilers.lcc.
(Note that lcc and lcc-win32 are two different things, one derived
from the other; see the relevant web pages for details.)
 
J

jacob navia

Gordon Burditt a écrit :
Does the following compile?

int foo(void)
{
float qfloat, class, new, delete;

/* ... bunch of stuff that uses these variables */
return 0;
}

If 'qfloat' is a built-in typedef or something similar, you've
got problems. If, on the other hand, you have to include <qfloat.h>
in order to use the qfloat type, you're OK.

THANKS!

I have just discovered a bug (<grin>)

I was initializing types before I parsed the command line options,
so qfloat would always be defined even if you specified -ansic.

I have fixed this, and now your example compiles without any
problems with lcc -ansic

jacob
 
K

Keith Thompson

jacob navia said:
lcw1964 a écrit :

Yes. There is a political rat's nest here.

Some people in this group, think that lcc-win32 is a bad compiler
since it has good features in it.

Nonsense. Nobody has said that, or anything resembling it. A number
of us have explained in detail our objections to the way you promote
lcc-win32's extensions in this newsgroup. You have repeatedly
responded to these objections as if people were attacking the compiler
itself, or you personally. (And yes, sometimes we get frustrated.)

Try to understand our arguments without filtering them through your
own preconceptions.

lcc-win32 implements some possibly useful extensions. There's nothing
wrong with that, and I don't recall anybody attacking you for it.

Any code that depends on those extensions will not be portable to
compilers other than lcc-win32, or to platforms that lcc-win32 doesn't
support. (The name implies that it supports only 32-bit Windows; is
that correct?) It's very important for potential users to be aware of
that fact. You often suggest specific features supported only by
lcc-win32 without mentioning the portability issue.

Languages based on C are not C, and are not topical in comp.lang.c.
For example, C++, Objective C, and the extended C-like language
supported by lcc-win32 are not C, and are off-topic here. Each of
these has one or more newsgroups in which it is perfectly topical. I
don't think a brief suggestion that another language might be useful,
with a pointer to an apropriate newsgroup, would be objectionable.
Detailed discussions of these non-C languages are objectionable.

Of all the things you've posted here that people have complained
about, I can't think of any that I'd consider inappropriate if you had
posted them to comp.compilers.lcc. Think about that.

[snip]
Just use it. I think you will like it because there are features
like 100 digit precision floats that you will be pressed to find
elsewhere. The math libraries are very extended, as you have noticed.

Sure, go ahead and use it *if* you don't mind paying the price in loss
of portability. And if you have any questions about the extensions,
please ask them in comp.compilers.lcc, not here.
 
P

P.J. Plauger

My question is this--does MinGW offer the "true" long double floating
point 80bit type, and if so how can I get my programs to display
results of the sort I mentioned in the previous paragraph is printf()
needs recasting to double in order to handle it?

Gosh, after all this noise, I'm not sure you still care about an
answer to your original question, but here it is. Mingw fails to
set the FPP in a proper state at program startup to do long double
arithmetic well. Our library executes:

fesetenv(FE_DFL_ENV); // correct FPP mode

whenever we use the native Mingw library and it works much better.
(It's still nowhere near as good as our library, but what with all
the flak about promoting third-party libraries, I hesitate to
mention that. You will notice, however, that *we* found the bug --
years ago. That tells you something about who tests what.)

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
K

Keith Thompson

jacob navia said:
Excuse me but "Future directions" means what it says: the directions
the comitee wants to follow in future issues of the standard.

Besides, in the paragraph J: "Common extensions" we have:

< quote >
J.5.6 Other arithmetic types
1 Additional arithmetic types, such as _ _int128 or double double, and
their appropriate conversions are defined (6.2.5, 6.3.1). Additional
floating types may have more range or precision than long double, may
be
used for evaluating expressions of other floating types, and may be used
to define float_t or double_t.

< end quote >

Providing __int128 or double double would not break any strictly
conforming code. The identifier __int128 is in the implementation's
namespace, and "double double" is a syntax error; no strictly
conforming program can use either.
This means that qfloat is included in the "common extensions" feature of
the standard, that explicitely mentions things that are not standard
but sufficiently common to be OKed, even if this is not normative.

There's no mention of "qfloat" in the standard.

If I can't use "qfloat" as an identifier in my own code, then the
implementation is non-conforming. If I can't use "qfloat" as an
identifier *and* use your extension, then you've implemented your
extension in a non-conforming manner.

You're allowed to do so, but I object to your insistence on discussing
it here.
All this extensions can be disabled when invoking the compiler with
-ansic flag.

That's good, seriously.
 
R

Richard Heathfield

Keith Thompson said:
[...]
All this extensions can be disabled when invoking the compiler with
-ansic flag.

That's good, seriously.

But it's not true (at least for the qfloat thing), for any users that
obtained their copy of lcc-win32 prior to this discussion (see elsethread,
where Mr Navia admits that he's had to fix the compiler as a result of this
discussion).

Up until now, many of us have taken Mr Navia's claims about
conformance-on-request at face value. But now one cannot help but wonder
how many other similar conformance issues exist within lcc-win32, as yet
undetected by Mr Navia.
 
K

Keith Thompson

lcw1964 said:
I have recompiled some old math code that uses long double types
throughout and provides the corresponding range and precision (up to 18
digits, with exponents up to about -/+ 4900) when compiled under an
older version of BC++.

You're making an assumption about the correct range and precision of
long double.
In the MinGW incarnation of gcc, I have made a couple of adjustments to
get it to compile--in particular, _atold() doesn't exist, and atof() is
prototyped only in stdlib.h whereas in BC++ it is listed in math.h too.

MinGW is correct about atof(); according to the standard, it's
not in <math.h>. _atold() is non-standard said:
However, I kept all of my long double declarations and outputs as that,
and used all of the long double versions of the math functions--expl(),
fabsl(), etc. The file complied but the output was gibberish. It took a
little googling to find that I had to recast the long double output as
double so printf() could meaningfully display it.

No, you just have to use the correct format. Use "%e", "%g", or "%f"
for float or double (float is promoted to double in a call to
printf()); use "%Le", "Lg", or "%Lf" for long double.
However, I have come to suspect that MinGW's long double isn't really
long double, and that somewhere in the process the range and precision
of of the floating point math has been restricted to the double range.
For example, in the original code under BC++ (not MSVC++, which is well
known to recast everything as double) I can generate a meaningful
answer of, say 1.34598900000098888e-2345, whereas the MinGW compiled
version will render this tiny value as simply 0.

C defines three floating-point types: float, double, and long double.
The standard requires float to have a precision of at least 6 decimal
digits; double and long double require at least 10. The maximum
representable value for all three types is required to be at least
1E+37.

There's no requirement for long double to be bigger than double; they
could have exactly the same representation (just as short and int or
int and long often have the same representation). The type "long
double" exists to *allow* an implementation to provide a large type,
not to require it.
My question is this--does MinGW offer the "true" long double floating
point 80bit type, and if so how can I get my programs to display
results of the sort I mentioned in the previous paragraph is printf()
needs recasting to double in order to handle it?

I don't know whether MinGW offers a long double type bigger than
double, though the fact that you had trouble printing long double
values makes me suspect that it does.

Try compiling and executing this program:

#include <float.h>
#include <limits.h>
#include <stdio.h>
int main(void)
{
printf("float is %d bits\n", CHAR_BIT * (int)sizeof(float));
printf("double is %d bits\n", CHAR_BIT * (int)sizeof(double));
printf("long double is %d bits\n", CHAR_BIT * (int)sizeof(long double));
printf("\n");

printf("FLT_DIG = %d\n", FLT_DIG);
printf("DBL_DIG = %d\n", DBL_DIG);
printf("LDBL_DIG = %d\n", LDBL_DIG);
printf("\n");

printf("FLT_MIN = %g\n", FLT_MIN);
printf("DBL_MIN = %g\n", DBL_MIN);
printf("LDBL_MIN = %Lg\n", LDBL_MIN);
printf("\n");

printf("FLT_MAX = %g\n", FLT_MAX);
printf("DBL_MAX = %g\n", DBL_MAX);
printf("LDBL_MAX = %Lg\n", LDBL_MAX);

return 0;
}

Note that the number of bits doesn't necessarily mean that all those
bits are used; you might have a 96-bit long double of which only 80
bits are actually used.

There's another potential problem. An implementation consists of two
parts, the compiler and the runtime library (plus the linker and
perhaps a few other things). Very often the runtime library is
provided as part of the operating system, and the compiler is provided
by a third party, so they might not be in sync. If your compiler
assumes that long double has one representation, and your runtime
library's implementation of printf() assumes a different
representation, you're going to have problems. In that case, you have
a non-conforming (broken) implementation -- and there might not be
much you can do about it.
 
J

jacob navia

P.J. Plauger a écrit :
Gosh, after all this noise, I'm not sure you still care about an
answer to your original question, but here it is. Mingw fails to
set the FPP in a proper state at program startup to do long double
arithmetic well. Our library executes:

fesetenv(FE_DFL_ENV); // correct FPP mode

whenever we use the native Mingw library and it works much better.
(It's still nowhere near as good as our library, but what with all
the flak about promoting third-party libraries, I hesitate to
mention that. You will notice, however, that *we* found the bug --
years ago. That tells you something about who tests what.)

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com

This is unclear.

FE_DFL_ENV is a macro that "designates the default environment"
as the standard says (7.6.1)

Specifically in this case however, do you set the FPU at full precision
(80 bits) or you stay in 64 bit mode?

lcc-win32 sets full precision at 80 bits.

The other problem with mingw is the run time library. Last time
I checked they do not provide a C99 compliant printf, so it is very
difficult to print long double data.
 
J

jacob navia

The mingw documentation says:
http://www.mingw.org/MinGWiki/index.php/long double

< quote >
Minimalist GNU for Windows
Printing and formatting long double values

mingw uses the Microsoft C run-time libraries and their implementation
of printf does not support the 'long double' type. As a work-around, you
could cast to 'double' and pass that to printf instead. For example:

printf("value = %g\n", (double) my_long_double_value);

Note that a similar problem exists for 'long long' type. Use the 'I64'
(eye sixty-four) length modifier instead of gcc's 'll' (ell ell). For
example:

printf("value = %I64d\n", my_long_long_value);

See also long long

< end quote >
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top