gmane.comp.compilers.pcc
http://permalink.gmane.org/gmane.comp.compilers.pcc
hourly11901-01-01T00:00+00:00Gmanehttp://gmane.org/img/gmane-25t.png
http://gmane.org
Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3663
<pre>
I think the point was that PCC and other non-optimizing compilers will
fail to optimize out the redundant check (it's redundant as long as
int has more bits than float, which you expect to be true, and which
is always true on POSIX implementations with Annex F).
Rich
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Rich Felker2015-05-21T20:00:23Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3662
<pre>* Gregory Heytings <ghe< at >sdf.org> [2015-05-21 17:29:05 +0200]:
no
if (-x <= INT_MIN || (x <= INT_MIN-1.f && x != INT_MIN)) goto overflow;
is always a good check, that's why it is better.
you could write it as
if (-x <= INT_MIN || (x <= INT_MIN-1.f && x < INT_MIN)) goto overflow;
too.
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Szabolcs Nagy2015-05-21T19:27:47Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3661
<pre>
Sizeof does not determine anything about value ranges. Except for char
it could be including all sorts of padding bits. Instead you need to
compare FLT_MANT_DIG and log2(INT_MAX+1). The latter can be computed
as a constant expression valid even in the preprocessor with this
handy macro:
/* Number of bits in inttype_MAX, or in any (1<<b)-1 where 0 <= b < 3E+10 */
#define IMAX_BITS(m) ((m) /((m)%0x3fffffffL+1) /0x3fffffffL %0x3fffffffL *30 \
+ (m)%0x3fffffffL /((m)%31+1)/31%31*5 + 4-12/((m)%31+3))
As noted in the comment, this works for _sizes_ (not values, sizes!)
of int up to ~3GB. Credit goes to Hallvard B. Furuseth, who posted
this on comp.lang.c a long time ago; the links I have don't seem to be
working. There's also a simpler version I can't find at the moment
that "only" works for more reasonable sizes of int (still much larger
than it would ever really be by many orders of magnitude). Anyway you
would use it something like:
#if IMAX_BITS(INT_MAX) >= FLT_MANT_DIG
if (-x <= INT_</pre>Rich Felker2015-05-21T17:02:10Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3660
<pre>
Okay, so in short one could write:
if (sizeof (float) <= sizeof (int))
if (-x <= INT_MIN || x < INT_MIN) goto overflow;
else
if (-x <= INT_MIN || (x <= INT_MIN-1.f && x != INT_MIN)) goto overflow;
And perhaps select one at compile time, but alas sizeof cannot be used in
a preprocessor directive; I guess most compilers calculate the sizeof
comparison anyway, at least when optimization is turned on, and select the
correct overflow check. I leave the "x != INT_MIN" check in the second
check, just in case INT_MIN-1.f == INT_MIN even if sizeof (float) > sizeof
(int).
Gregory
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Gregory Heytings2015-05-21T15:29:05Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3659
<pre>
Actually it's worse. In default rounding mode, assuming int has more
bits than float, INT_MIN-1.0f is equal to (float)INT_MIN. So
x<=INT_MIN results in goto overflow, despite x==INT_MIN being a
non-overflow case. Excess precision might fix this bug. :-)
Rich
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Rich Felker2015-05-20T22:49:55Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3658
<pre>* Gregory Heytings <ghe< at >sdf.org> [2015-05-20 23:52:02 +0200]:
i think they may not be the same if FLT_EVAL_METHOD != 0
i think implicit conversion result may be represented with higher range and
precision than the type (float here), but when a cast is used the extra
precision must be removed (this is not a problem in this case: INT_MIN is
a power of 2 that is most likely exactly representible as a float).
otherwise the two expressions are the same.
float values between INT_MIN-1.f and INT_MIN dont overflow
(of course if INT_MIN-1.f == INT_MIN then the check is
ok and that's what happens in practice with 32bit int
and ieee binary32 float)
i think a better check is
if (-x <= INT_MIN || (x <= INT_MIN-1.f && x != INT_MIN)) goto overflow;
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Szabolcs Nagy2015-05-20T22:48:12Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3657
<pre>
By the way, is there a difference between "- (float) INT_MIN" and "-1.0f *
INT_MIN"?
This one is really neat! Ignoring the last problem you mentioned, the
check would then be:
if (-x <= INT_MIN || x < INT_MIN) goto overflow;
Gregory
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Gregory Heytings2015-05-20T21:52:02Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3656
<pre>Quoting Rich Felker <dalias< at >libc.org>:
Agreed. Missing a (float) cast.
Or, (-x <= INT_MIN)
I believe that the result would still be correct with the excess
precision.
</pre>Fred J. Tydeman2015-05-20T19:16:33Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3655
<pre>
-INT_MIN is already UB. I assume you meant to use my test for the
positive overflow. Alternatively you could use -1.0f*INT_MIN which may
be more intuitive.
For the negative case, INT_MIN-1.F may have excess precision if
FLT_EVAL_METHOD!=0, thus giving the wrong result. A cast to (float)
would fix this on conforming compilers but I don't know if pcc does
this correctly; old gcc versions, and even new ones if you don't use
-std=c99 or c11, do it wrong. You probably want an explicit
conditional based on limits.h and float.h to only subtract 1.F if you
know the result will be exact. (Non-default rounding modes could also
give the wrong result there, BTW.)
Rich
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Rich Felker2015-05-20T17:10:44Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3654
<pre>
Should this not be "if ((-(float)INT_MIN <= x)..."? Otherwise there is an
integer overflow. This is indeed equivalent, I think, to "x >=
(INT_MAX/2+1)*2.0f", but slightly shorter.
Gregory
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Gregory Heytings2015-05-20T16:59:50Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3653
<pre>Quoting Rich Felker <dalias< at >libc.org>:
There could be a problem if x has the value INT_MIN-0.9F
as that value converts to INT_MIN. The same holds for INT_MAX+0.9F;
those two problems only happen if float has more value bits than int.
I think the test should be (assuming INT_MAX+1 == -INT_MIN):
if( (-INT_MIN <= x) || (x <= (INT_MIN-1.F)) goto overflow;
</pre>Fred J. Tydeman2015-05-20T16:31:28Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3652
<pre>
I meant int and double, not long and double, which obvioulsly has
the same problem.
-Otto
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Otto Moerbeek2015-05-20T04:52:55Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3651
<pre>
Great, now everything is crystal clear! :) It's a nice trick, I am
surprised that it is not more well-known (I couldn't find it anywhere, but
perhaps I didn't look at the right place). I was a bit puzzled to see
that the comparison "x < INT_MIN" worked while "x > INT_MAX" didn't, now I
see why.
Gregory
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Gregory Heytings2015-05-19T21:46:38Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3650
<pre>
INT_MAX has all ones in its value bits, and that may be more bits than
the precision of the destination floating point type. INT_MAX+1 is a
power of two, so (assuming it's not astronomically huge) it's always
representable in any floating point type. Unfortunately we can't
compute INT_MAX+1 directly. It overflows as int, and there might not
be any larger integer type to perform the arithmetic in, and if we did
INT_MAX+1.0f then INT_MAX would get converted to float, with a loss of
precision, before the addition. So instead I take INT_MAX/2+1 to get a
power of two that's exactly half of the numerical value of INT_MAX+1,
then convert it to float (which is safe because it's a power of 2) and
multiply by 2 as float.
Rich
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Rich Felker2015-05-19T21:39:11Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3649
<pre>
Many thanks, indeed this trick appears to work... but I don't understand
it. Could you perhaps explain why it works?
Gregory
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Gregory Heytings2015-05-19T21:12:51Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3648
<pre>
Yes; it's fairly easy. Suppose x is the floating point value you want
to convert. Then use:
if (x >= (INT_MAX/2+1)*2.0f || x < INT_MIN) goto overflow;
This assumes INT_MIN is a power of two, i.e. INT_MIN!=-INT_MAX. Since
the C standard allows INT_MIN==-INT_MAX, you might want to consider
that case too; personally, I don't bother. Handling it would require a
trick like what I did for INT_MAX above.
Rich
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Rich Felker2015-05-19T20:59:54Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3647
<pre>
Actually it doesn't, you have the exact same problem with doubles:
#include <limits.h>
#include <stdio.h>
int main ()
{
long i = LONG_MAX, l = 0; double f;
while (1) { f = (double) i + l; if (f > LONG_MAX) { l--; break; }; l++; }
printf ("%ld\n", l);
f = (double) i + l;
if (f <= LONG_MAX) { i = (long) f; printf ("%ld\n", i); }
return 0;
}
Which prints "1024 -9223372036854775808".
Gregory
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Gregory Heytings2015-05-19T19:59:42Re: Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3646
<pre>
Some thoughs: 32-bit floats cannot represent each integer value near
INT_MAX. So (float) i + l already is not exact.
Switching to double solves your problem. I'm sure this is not the full
explanation, but it's a start.
-Otto
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc
</pre>Otto Moerbeek2015-05-19T19:51:36Converting floating to integral
http://permalink.gmane.org/gmane.comp.compilers.pcc/3645
<pre>
Hi,
I have an apparently simple question, to which I could not find a clear
answer anywhere. Given that it is somewhat related to PCC, and that there
are many C experts on this list, I dare to ask it here.
The C standard explains that "When a value of floating type is converted
to integral type, the fractional part is discarded. If the value of the
integral part cannot be represented by the integral type, the behavior is
undefined." These are the C90 words (3.2.1.3), the C99 specification is
similar (6.3.1.4). So far so good.
The question is: is it possible to check whether an floating value will
fit in an integral type *before* doing the cast, to avoid undefined
behaviors?
Of course I first thought that a simple comparison would do the trick.
Something like "if (float_variable <= INT_MAX) do_cast; else
raise_error;". And indeed it appears to work... in most cases, but alas
not in all cases.
Consider the following program:
#include <limits.h>
#include <stdio.h>
int main ()
{
int i </pre>Gregory Heytings2015-05-19T19:18:33Re: Multiple issues still have PCC broken out-of-the-box with musl (and everywhere?)
http://permalink.gmane.org/gmane.comp.compilers.pcc/3644
<pre>stephen Turner skrev den 2015-05-14 15:04:
Pcc has a bunch of specific tests in pcc-tests (that can be checked out
of cvs).
Yoy can also look at
http://pcc.ludd.ltu.se/standards_and_regression_testing/ on how to use
other test suites.
</pre>Anders Magnusson2015-05-14T13:41:21Re: Multiple issues still have PCC broken out-of-the-box with musl (and everywhere?)
http://permalink.gmane.org/gmane.comp.compilers.pcc/3643
<pre>I re-ran the build script against the new musl 1.1.9 and it is still having
the same issue i reported before with make in the "glob" file(s)
Anders, I have been researching what i need to make a multi-platform chroot
build script and will post it once i get a chance to finish. I still need
to set up a bsd vm for my own testing. Later i will add the libc test
suite to the script once i figure out how im going to set up the pass/fail
portion so tests can be automated for new releases.
Is there generic tests for compilers that are recommended or a pcc specific
test suite?
thanks,
stephen
_______________________________________________
Pcc mailing list
Pcc< at >lists.ludd.ltu.se
https://lists.ludd.ltu.se/cgi-bin/mailman/listinfo/pcc</pre>stephen Turner2015-05-14T13:04:41Search EngineSearch the mailing list at Gmanequery
http://search.gmane.org/?group=$group=gmane.comp.compilers.pcc