ptrdiff_t maximum

G

Geoff

Are these (and the others from me, elsethread) results meaningful?

If not I'll just avoid posting them - I did report them because they
seem weird at best.

This one is definitely weird. It looks like printf is using two 32-bit
registers to make the long long in hex. Those are the wrong decimal
values as well. I haven't a clue what might be going on there.
 
I

Ian Collins

This one is definitely weird. It looks like printf is using two 32-bit
registers to make the long long in hex. Those are the wrong decimal
values as well. I haven't a clue what might be going on there.

It looks like the code was compiled in 32 bit mode, where %ll is being
used to format a long, not a long long.
 
F

Francesco S. Carta

This one is definitely weird. It looks like printf is using two 32-bit
registers to make the long long in hex. Those are the wrong decimal
values as well. I haven't a clue what might be going on there.

Well, if it could come interesting, I'm willing to run more tests, but I
need to be fed the code to run or the exact changes to make - just
consider me a plain "compiler interface", I'm just a nibble over
"C-unaware" ;-)

Note: ptrdiff_t seems to be defined as "long int" here (I might have got
lost in the various #ifdef and #define, though)
 
F

Francesco S. Carta

It looks like the code was compiled in 32 bit mode, where %ll is being
used to format a long, not a long long.

I have no idea about how to compile in 64-bit mode... any hint while I'm
searching the web about this?
 
I

Ian Collins

Note: ptrdiff_t seems to be defined as "long int" here (I might have got
lost in the various #ifdef and #define, though)

So you probably have to add an option to get a 64 bit compile.
 
F

Francesco S. Carta

I have no idea about how to compile in 64-bit mode... any hint while I'm
searching the web about this?

Uhm, my MinGW package seems to be just 32 bit, I've found a 64 bit
snapshot on Sourceforge but I'd have to build it, and I never ever did
anything like that.

Never mind, sorry for the noise added.
 
G

Geoff

I have no idea about how to compile in 64-bit mode... any hint while I'm
searching the web about this?

It looks like the command line switch for gcc (mingw) is -m64
 
B

Ben Bacarisse

Peter Nilsson said:
Oops, should be...

for (max = 32767; (new = 2ul * max + 1) > max; )

That swaps overflow for an out-of-range conversion which is
implementation defined and can raise a signal (in C99).
 
B

Ben Bacarisse

Ian Collins said:
Or:

#include <stdio.h>
#include <stddef.h>
#include <limits.h>

int main()
{
printf("ptrdiff_t maximum %ld\n",
(long)(~(1UL<<(sizeof(ptrdiff_t)*CHAR_BIT-1))));
}

Note: that's C90 only. In C99 you'd have to use intmax_t. I think
that's safe -- ptrdiff_t can't be wider than intmax_t.

All these methods fall foul of the dreaded padding bits.
 
F

Francesco S. Carta

The last code above on:
MinGW 4.4.0, Windows7, AMD Athlon(tm) II Dual-Core M300 2.00 Ghz

Gives:
ptrdiff_t maximum 7fffffff7fffffff = 8541177558308426082
ptrdiff_t minimum 8000000080000000 = 8541177558308426082

I found a compiled package for MinGW 4.5 64bit, and now I get the same
exact results as Geoff's.
 
F

Francesco S. Carta

I pasted and posted too quick. I think you wanted something like this:

# include<stdio.h>
# include<stddef.h>

int main(void) {

ptrdiff_t last, next;

for (last = 32767; (next = 2 * (double)last + 1)> last; ) {
printf ("last = %lld double = %f next = %lld\n",
(long long)last, 2 * (double)last, (long long)next);
last = next;

}
printf("%lld\n", (long long) last);
return 0;
}

With the MinGW64 4.5 I just installed I got the same exact result of
yours on the first run (without any optimization), except that setting
the -O2 flag I got this:

last = 32767 double = 65534.000000 next = 65535
last = 65535 double = 131070.000000 next = 131071
last = 131071 double = 262142.000000 next = 262143
last = 262143 double = 524286.000000 next = 524287
last = 524287 double = 1048574.000000 next = 1048575
last = 1048575 double = 2097150.000000 next = 2097151
last = 2097151 double = 4194302.000000 next = 4194303
last = 4194303 double = 8388606.000000 next = 8388607
last = 8388607 double = 16777214.000000 next = 16777215
last = 16777215 double = 33554430.000000 next = 33554431
last = 33554431 double = 67108862.000000 next = 67108863
last = 67108863 double = 134217726.000000 next = 134217727
last = 134217727 double = 268435454.000000 next = 268435455
last = 268435455 double = 536870910.000000 next = 536870911
last = 536870911 double = 1073741822.000000 next = 1073741823
last = 1073741823 double = 2147483646.000000 next = 2147483647
last = 2147483647 double = 4294967294.000000 next = 4294967295
last = 4294967295 double = 8589934590.000000 next = 8589934591
last = 8589934591 double = 17179869182.000000 next = 17179869183
last = 17179869183 double = 34359738366.000000 next = 34359738367
last = 34359738367 double = 68719476734.000000 next = 68719476735
last = 68719476735 double = 137438953470.000000 next = 137438953471
last = 137438953471 double = 274877906942.000000 next = 274877906943
last = 274877906943 double = 549755813886.000000 next = 549755813887
last = 549755813887 double = 1099511627774.000000 next = 1099511627775
last = 1099511627775 double = 2199023255550.000000 next = 2199023255551
last = 2199023255551 double = 4398046511102.000000 next = 4398046511103
last = 4398046511103 double = 8796093022206.000000 next = 8796093022207
last = 8796093022207 double = 17592186044414.000000 next = 17592186044415
last = 17592186044415 double = 35184372088830.000000 next = 35184372088831
last = 35184372088831 double = 70368744177662.000000 next = 70368744177663
last = 70368744177663 double = 140737488355326.000000 next = 140737488355327
last = 140737488355327 double = 281474976710654.000000 next =
281474976710655
last = 281474976710655 double = 562949953421310.000000 next =
562949953421311
last = 562949953421311 double = 1125899906842622.000000 next =
1125899906842623
last = 1125899906842623 double = 2251799813685246.000000 next =
2251799813685247
last = 2251799813685247 double = 4503599627370494.000000 next =
4503599627370495
last = 4503599627370495 double = 9007199254740990.000000 next =
9007199254740991
last = 9007199254740991 double = 18014398509481982.000000 next =
18014398509481984
last = 18014398509481984 double = 36028797018963968.000000 next =
36028797018963968
last = 36028797018963968 double = 72057594037927936.000000 next =
72057594037927936
last = 72057594037927936 double = 144115188075855870.000000 next =
144115188075855872
last = 144115188075855872 double = 288230376151711740.000000 next =
288230376151711744
last = 288230376151711744 double = 576460752303423490.000000 next =
576460752303423488
last = 576460752303423488 double = 1152921504606847000.000000 next =
1152921504606846976
last = 1152921504606846976 double = 2305843009213694000.000000 next =
2305843009213693952
last = 2305843009213693952 double = 4611686018427387900.000000 next =
4611686018427387904
last = 4611686018427387904 double = 9223372036854775800.000000 next =
-9223372036854775808
-9223372036854775808

Just out of curiosity, are these warnings expected?

In function 'main':|
main.c|10|warning: unknown conversion type character 'l' in format|
main.c|10|warning: format '%f' expects type 'double', but argument 2 has
type 'ptrdiff_t'|
main.c|10|warning: unknown conversion type character 'l' in format|
main.c|10|warning: too many arguments for format|
main.c|14|warning: unknown conversion type character 'l' in format|
main.c|14|warning: too many arguments for format|
||=== Build finished: 0 errors, 6 warnings ===|

Maybe I downloaded a buggy package? Heck, better that I stop posting
this stuff and I get something sure about my toolchain.
 
I

Ian Collins

Note: that's C90 only. In C99 you'd have to use intmax_t. I think
that's safe -- ptrdiff_t can't be wider than intmax_t.

In C99, all you need is

printf("ptrdiff_t maximum %ld\n", PTRDIFF_MAX);

:)
All these methods fall foul of the dreaded padding bits.

Dreaded or mythical?
 
G

Geoff

Just out of curiosity, are these warnings expected?

In function 'main':|
main.c|10|warning: unknown conversion type character 'l' in format|
main.c|10|warning: format '%f' expects type 'double', but argument 2 has
type 'ptrdiff_t'|
main.c|10|warning: unknown conversion type character 'l' in format|
main.c|10|warning: too many arguments for format|
main.c|14|warning: unknown conversion type character 'l' in format|
main.c|14|warning: too many arguments for format|
||=== Build finished: 0 errors, 6 warnings ===|

Maybe I downloaded a buggy package? Heck, better that I stop posting
this stuff and I get something sure about my toolchain.

I didn't get any warnings. Your compiler appears to not need the %lld,
use %ld instead.
 
J

John Kelly

Note: that's C90 only. In C99 you'd have to use intmax_t. I think
that's safe -- ptrdiff_t can't be wider than intmax_t.

All these methods fall foul of the dreaded padding bits.


How about (double) cast the signed type before multiplication

for (max = 32767; (new = 2 * (double)max + 1) > max;)
 
U

Uno

Geoff said:
... and to include <stdint.h>

:)

I don't think you want the l either:

$ gcc -std=c99 -Wall -Wextra jk1.c -o out
jk1.c: In function ‘main’:
jk1.c:13: warning: format ‘%ld’ expects type ‘long int’, but argument 2
has type ‘int’
$ gcc -std=c99 -Wall -Wextra jk1.c -o out
$ ./out
ptrdiff_t max1 is 2147483647
ptrdiff_t max2 is 2147483647
$ cat jk1.c
# include <stddef.h>
# include <stdio.h>
# include <stdint.h>

int
main (void)
{
ptrdiff_t const dx =
((ptrdiff_t) ~ ((ptrdiff_t) - 1 < 1 ? (-1 - (((ptrdiff_t) 1
<< (sizeof (ptrdiff_t) * 8 - 2)) - 1 +
((ptrdiff_t) 1
<< (sizeof (ptrdiff_t) * 8 - 2)))) :
(ptrdiff_t) 0));
printf ("ptrdiff_t max1 is %d\n", dx);
printf("ptrdiff_t max2 is %d\n", PTRDIFF_MAX);
return 0;
}
// gcc -std=c99 -Wall -Wextra jk1.c -o out
$
 
J

John Kelly

Where's the chunder bucket?

Seems to work.

If it loses precision approaching the 64th bit, that's acceptable for
purposes of trim(). I only need to stay under the limit, without going
over.

I need the limit to prevent infinite loops. To accommodate big strings,
I want a large limit, but at those magnitudes the precision, relative to
an exact integer value, is not important.
 

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

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top