64-bit integers where the implementation supports max 32-bit ints

I

Ian Collins

Keith said:
Malcolm McLean said:
sizeof sint_t 8

sizeof uint_t 8

The above set is for the 64-bit target which is why [su]int_t have size 8.
(I believe gcc defaults to 4 byte ints on 64-bit targets.)
int should be the natural register size, which means 64 bits on a 64 bit
system. That also means that, expect for the annoying but practically
unimportant case of a byte array that takes up over half the memory,
int can index any array.

Perhaps it "should". Nevertheless, int is typically 32 bits on 64-bit
systems, probably because making it 64 bits would mean you can't have
both a 16-bit type and a 32-bit type (unless the implementation resorts
to extended integer types).

More likely a mixture of too much fragile code that assumes 32 bit int
and more importantly for new code, performance.
 
J

James Harris

Stephen Sprunk said:
sizeof sint_t 8
sizeof uint_t 8

The above set is for the 64-bit target which is why [su]int_t have
size 8. (I believe gcc defaults to 4 byte ints on 64-bit targets.)

int should be the natural register size, which means 64 bits on a 64
bit system.

Of course, that assumes a useful definition of "natural". For instance,
there are three common models for "64-bit" machines: ILP64, I32LP64 and
IL32LLP64. And proponents of each will explain why their model is more
"natural" than the others.

I'm not familiar with the notation but taking a guess that they mean

ILP64 - int, long and pointers all 64 bit
I32LP64 - int 32, long and pointers 64
IL32LLP64 - int and long 32, long long and pointers 64
That assumes an int is as wide as a void*, which is not true on I32LP64
and IL32LLP64 systems, e.g. Linux and Windows on x86-64.

Is there a type that should be used as index of a potentially very large
array? size_t? ptrdiff_t? unsigned long long?

James
 
S

Stephen Sprunk

I'm not familiar with the notation but taking a guess that they mean

ILP64 - int, long and pointers all 64 bit I32LP64 - int 32, long and
pointers 64 IL32LLP64 - int and long 32, long long and pointers 64
Exactly.


Is there a type that should be used as index of a potentially very
large array? size_t? ptrdiff_t? unsigned long long?

While theoretically possible, it's unlikely that any implementation is
capable of creating an object (including an array) larger than size_t
can count.

S
 
M

Malcolm McLean

That assumes an int is as wide as a void*, which is not true on I32LP64
and IL32LLP64 systems, e.g. Linux and Windows on x86-64.
The alternative is to patch the compiler so that objects greater
than 2MB in size can't be created. For the vast majority of programs,that
won't be a problem. However if someone does have a machine with a massive
memory, they'll expect to be able to declare massive flat array, so it's
not psychologically a good solution.
 
R

Rosario1903

Stephen Sprunk said:
On Tuesday, August 6, 2013 3:12:47 PM UTC+1, James Harris wrote:
sizeof sint_t 8
sizeof uint_t 8

The above set is for the 64-bit target which is why [su]int_t have
size 8. (I believe gcc defaults to 4 byte ints on 64-bit targets.)

int should be the natural register size, which means 64 bits on a 64
bit system.

Of course, that assumes a useful definition of "natural". For instance,
there are three common models for "64-bit" machines: ILP64, I32LP64 and
IL32LLP64. And proponents of each will explain why their model is more
"natural" than the others.

I'm not familiar with the notation but taking a guess that they mean

ILP64 - int, long and pointers all 64 bit
I32LP64 - int 32, long and pointers 64
IL32LLP64 - int and long 32, long long and pointers 64
I32L32LL64P32LP64
That assumes an int is as wide as a void*, which is not true on I32LP64
and IL32LLP64 systems, e.g. Linux and Windows on x86-64.

Is there a type that should be used as index of a potentially very large
array? size_t? ptrdiff_t? unsigned long long?

James
 
K

Keith Thompson

Rosario1903 said:
I32L32LL64P32LP64

What?

The "I32L32" portion, if it's suppose to mean 32-bit int and 32-bit
long, is usually written "IL32".

Is "P32LP64" supposed to mean 32-bit pointers and 64-bit "long
pointers"? If so, what the heck is a "long pointer"?
 
R

Rosario1903

What?

The "I32L32" portion, if it's suppose to mean 32-bit int and 32-bit
long, is usually written "IL32".

Is "P32LP64" supposed to mean 32-bit pointers and 64-bit "long
pointers"? If so, what the heck is a "long pointer"?

a pointer one have to use for see one film with len > 4GB
 
K

Keith Thompson

Rosario1903 said:
Rosario1903 said:
On Wed, 7 Aug 2013 11:11:11 +0100, "James Harris" wrote: [...]
I'm not familiar with the notation but taking a guess that they mean

ILP64 - int, long and pointers all 64 bit
I32LP64 - int 32, long and pointers 64
IL32LLP64 - int and long 32, long long and pointers 64

I32L32LL64P32LP64

What?

The "I32L32" portion, if it's suppose to mean 32-bit int and 32-bit
long, is usually written "IL32".

Is "P32LP64" supposed to mean 32-bit pointers and 64-bit "long
pointers"? If so, what the heck is a "long pointer"?

a pointer one have to use for see one film with len > 4GB

Pointers point into (in-memory) objects, not into files.
 
R

Rosario1903

Rosario1903 said:
On Wed, 7 Aug 2013 11:11:11 +0100, "James Harris" wrote: [...]
I'm not familiar with the notation but taking a guess that they mean

ILP64 - int, long and pointers all 64 bit
I32LP64 - int 32, long and pointers 64
IL32LLP64 - int and long 32, long long and pointers 64

I32L32LL64P32LP64

What?

The "I32L32" portion, if it's suppose to mean 32-bit int and 32-bit
long, is usually written "IL32".

Is "P32LP64" supposed to mean 32-bit pointers and 64-bit "long
pointers"? If so, what the heck is a "long pointer"?

a pointer one have to use for see one film with len > 4GB

i think would be ok one cpu that has 2 kind of registers
one for 8 bit and one for 32 bit

the short 16 bit would be a composed type 2 8bit
with the usual big number routines for size 2
or would use the routine for 32 bit for doing operation on 16
the int and the long would be type 32 bit
the long long 64 bit would be type 2 32 bit
with the usual big number routines for array of size 2
the pointer would be 32 bit flat address space
and against the standard of C would be void*
the long pointer would be type 2 unsigned 2 complement 32 bit
with the usual big number routines for array of size 2
and something for dereference the flat 64 bit address
for example the simbol °

u8,u16,u32,u64
all the other u2^n type could be in what i think write as array of
u32 and big number routines

operator for deference 64 bit number something as
u8 °p, c;

p is a long pointer [64 bit that point to char]
so c=°p would deference the pointer of 64 bit for obtain in its
position c...

all the same for what * means in C etc
u32 k;
u32 °v=&k;
u8 °°p=(u8°°)&v;

possible i don't know what i wrote

for fpu i would do some test for see how is slow fixed point 64 bit
build on unsigned against float IEEE
 
K

Keith Thompson

Rosario1903 said:
but for some reason files i think would be load in the memory

If a file is bigger that `SIZE_MAX` bytes (where `SIZE_MAX` is the
maximum value of type `size_t`), then you won't be able to load all of
it into memory. If you need to be able to load huge files into memory,
you just need big pointers (like the 64-bit pointers that are becomming
more common these days.)

Large files are usually processed by loading only parts of them into
memory at a time.
 
J

Joe Pfeiffer

Rosario1903 said:
but for some reason files i think would be load in the memory

Not in general, no. And when you do map a file into memory (with
mmap(), for instance), they become in-memory objects, and therefore you
are pointing at in-memory objects. If your (flat) memory space is >4GB,
you need a pointer longer than 32 bits so you've still just got P64.
 
P

Phil Carmody

Stephen Sprunk said:
That's an understatement.

I'm aghast he's not been broadly relegated to killfiles yet. From
other newsgroups I've known he's ineducable for about a decade; his
arrival in c.l.c made it perfectly clear nothing has changed. Perhaps
he's not quite the dysfunctional troll that he has been elsewhere, but
still not worth wasting keystrokes on.

Phil
 
R

Rosario1903

for fpu i would do some test for see how is slow fixed point 64 bit
build on unsigned against float IEEE

time and result for doing operations

fixed point using only 32 bit unsigned array [32.64 bit] vs IEEE
double 64 bit

a little slow the fixed point[from 8x to 25x] but one have to get in
count that there are 90_000_000 of operations each operator +-*/

than i don't know if my implementation is ok, could return one error
number, if someone see some wrong number could please say that?

there is someone can propose good set of operation for stress these
float numbers operator?

if see these result i dubit that fpu is essential

base_10=16 precision=2
+Fixed point result=1009.000000 time=8.000000
+IEEE Double result=1008.999997 time=1.000000
-Fixed point result=1000.000000 time=10.000000
-IEEE Double result=1000.000000 time=1.000000
*Fixed point result=8103080.281151 time=18.000000
*IEEE Double result=8103080.323769 time=1.000000
/Fixed point result=1000.000000 time=55.000000
/IEEE Double result=100.000000e1 time=2.000000


#include "myh.h"
#include <time.h>

#define uns unsigned
#define u32 unsigned
#define u64 unsigned __int64
#define i32 int
#define u16 unsigned short
#define u8 unsigned char
#define i8 char
#define i16 short
#define long_long __int64
#define sdC __stdcall
#define ooo cout
#define S sizeof
#define MM Malloc_m
#define FF Free_m

#define F for
#define R return
#define W while
#define G goto

int testVsFloat(void)
{double da, db;
time_t ti, tf;
fnum a, b; /* fixed point float */
u32 i;

set_precision10(16); // for float: 2 unsigned as at right of .

/* + */
ti=time(0);
F(i=0, a=0.0000001, b=1000.0; i<90000000; ++i)
b=b+a;
ooo<<"+Fixed point result="<<b<<" ";
tf=time(0);
P("time=%f\n", difftime(tf, ti));

ti=time(0);
F(i=0, da=0.0000001, db=1000.0; i<90000000; ++i)
db=db+da;
P( "+IEEE Double result=%f ", db);
tf=time(0);
P("time=%f\n", difftime(tf, ti));

/* - */
ti=time(0);
F(i=0; i<90000000; ++i)
b=b-a;
ooo<<"-Fixed point result="<<b<<" ";
tf=time(0);
P("time=%f\n", difftime(tf, ti));

ti=time(0);
F(i=0; i<90000000; ++i)
db=db-da;
P( "-IEEE Double result=%f ", db);
tf=time(0);
P("time=%f\n", difftime(tf, ti));

/* * */
ti=time(0);
F(i=0, a=a+1; i<90000000; ++i)
b=b*a;
ooo<<"*Fixed point result="<<b<<" ";
tf=time(0);
P("time=%f\n", difftime(tf, ti));

ti=time(0);
F(i=0, da=da+1; i<90000000; ++i)
db=db*da;
P( "*IEEE Double result=%f ", db);
tf=time(0);
P("time=%f\n", difftime(tf, ti));

/* / */
ti=time(0);
F(i=0; i<90000000; ++i)
b=b/a;
ooo<<"/Fixed point result="<<b<<" ";
tf=time(0);
P("time=%f\n", difftime(tf, ti));

ti=time(0);
F(i=0; i<90000000; ++i)
db=db/da;
P( "/IEEE Double result=%f ", db);
tf=time(0);
P("time=%f\n", difftime(tf, ti));

}


int main27(int c, char** a)
{testVsFloat();
R 0;
}
 
K

Keith Thompson

Rosario1903 said:
#define ooo cout
#define S sizeof
#define MM Malloc_m
#define FF Free_m

#define F for
#define R return
#define W while
#define G goto

And that's where I stopped reading.

I was happy to see that you seemed to have stopped using those stupid
little 1-letter macros. They make your code more difficult to read,
and it's just not worth the extra effort. If you start using them
here, I will go back to ignoring you.

And please don't post C++ code here.
 
T

Tim Rentsch

Eric Sosman said:
James Harris said:
news:[email protected]... [...]
FWIW the section of the header which defines the 64-bit types is
currently as follows. It's not fully tested yet.

/*
* 64-bit integers
*/

#if INT_MAX == 0x7fffffffffffffff
typedef signed int s64_t;
#elif LONG_MAX == 0x7fffffffffffffff
typedef signed long s64_t;
#elif LLONG_MAX == 0x7fffffffffffffff
typedef signed long long s64_t;
#else
typedef struct {u32_t low; s32_t high;} s64_t; /* Limited use */
#endif

This might cause problems if the 16-bit compiler's preprocessor can't
handle a 64-bit constant like 0x7fffffffffffffff. I'm not sure there's
a really good solution. But it's likely you'll only get some warnings,
and you can ignore them as long as it selects the right definition.
[...]

One approach is to write tests like

#if ((INT_MAX >> 16) >> 16) == 0x7fffffff

Details: We know that preprocessor arithmetic is equivalent to that
of the execution environment's widest integer types, which are no
narrower than `[unsigned] long', which are at least 32 bits wide.
Therefore, the 16-bit shifts above are well-defined (although a
31-bit shift of a signed value might not be), and two of them
eliminate 32 low-order bits. Also, we know that INT_MAX is one
less than a power of two, so if any 1-bits remain after shifting
we can conclude that all the eliminated bits were also 1's.

Similar arrangements like

#if ((INT_MAX >> 30) >> 30) == 0x7

would also work, in pretty much the same way.

What makes you think 31-bit shifts of signed values (in
preprocessor expressions, assuming a non-negative value
being shifted) don't have well-defined behavior? The
width of long must be at least 32 bits.
 

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
474,076
Messages
2,570,565
Members
47,200
Latest member
Vanessa98N

Latest Threads

Top