128 bit integers is on topic

J

jacob navia

The regulars said that speaking about 128 bit integers is off topic
since the code doesn't run under gcc, it is specific to lcc-win etc.

They have no clue actually. Gcc supports in some platforms 128 bit
integers. The syntax they use is:

int __attribute__((__mode__(__TI__))
unsignd int __attribute__((__mode__(__TI__))

References:
http://gcc.gnu.org/ml/gcc/2000-09/msg00419.html

Now that gcc supports them, (and not only lcc-win)
this will be accepted here I hope...

:)

jacob
 
N

Noob

Jacob said:
The regulars said that speaking about 128 bit integers is off topic
since the code doesn't run under gcc, it is specific to lcc-win etc.

You've missed the point. It is off-topic because it is non-standard,
not because few compilers implement it.

However, I think one could argue that widely-implemented extensions
are topical. e.g. the long long type before C99, although I think (??)
VC did not support it.
They have no clue actually.

C'est cela, oui...
Gcc supports in some platforms 128 bit
integers. The syntax they use is:

int __attribute__((__mode__(__TI__))
unsigned int __attribute__((__mode__(__TI__))

References:
http://gcc.gnu.org/ml/gcc/2000-09/msg00419.html

__uint128_t seems even easier to use.

http://www.x86-64.org/pipermail/discuss/2005-August/006412.html
Now that gcc supports them, (and not only lcc-win)
this will be accepted here I hope...

Non sequitur.
 
J

jacob navia

Richard Heathfield a écrit :
No, they don't. Learn to read. The C Standard explicitly allows
integer types to be wider than the minimum. 128 bit integers are
wider than the minimum. Therefore, the C Standard explicitly
allows them.

The following C code:

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

int main(void)
{
unsigned short n = USHRT_MAX;
printf("%hu\n", n);
return 0;
}

must print a value that is at least 65535, but nothing in
the C Standard prevents it from being 4294967295, or
18446744073709551615, or 340282366920938463463374607431768211455,
or 115792089237316195423570985008687907853269984665640564039457584007913129639935,
or even higher numbers (or indeed various values in between).

It is not 128-bit integers that are off-topic, but extensions
that are specific to implementations. Until C99, // was off-topic,
even though it was provided by plenty of implementations. When
C99 codified it, it became topical. If you want your extensions
to become topical here, get them put into the language definition.

<snip>

THEY ARE ALREADY

Read Appendix J.5 of the standard
 
K

karthikbalaguru

No, they don't. Learn to read. The C Standard explicitly allows
integer types to be wider than the minimum. 128 bit integers are
wider than the minimum. Therefore, the C Standard explicitly
allows them.

The following C code:

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

int main(void)
{
unsigned short n = USHRT_MAX;
printf("%hu\n", n);
return 0;

}

must print a value that is at least 65535, but nothing in
the C Standard prevents it from being 4294967295, or
18446744073709551615, or 340282366920938463463374607431768211455,
or 115792089237316195423570985008687907853269984665640564039457584007913129639935,
or even higher numbers (or indeed various values in between).

Exactly, it states that 'An int must be at least 16 bits long'

Karthik Balaguru
 
B

BGB / cr88192

jacob navia said:
The regulars said that speaking about 128 bit integers is off topic
since the code doesn't run under gcc, it is specific to lcc-win etc.

They have no clue actually. Gcc supports in some platforms 128 bit
integers. The syntax they use is:

int __attribute__((__mode__(__TI__))
unsignd int __attribute__((__mode__(__TI__))

yep, gcc and its usual horrid extension syntax...

References:
http://gcc.gnu.org/ml/gcc/2000-09/msg00419.html

Now that gcc supports them, (and not only lcc-win)
this will be accepted here I hope...

:)

probably not, since in the minds of the people here, this would mean
elevating gcc'isms to the level of the standard...


I use the syntax __int128 and __uint128 personally...

in my compiler, they are also supported by a modified 'inttypes.h', which
defines int128_t and uint128_t (at least for my compiler).

it is worth noting that MSVC does not have this header.


however, for use with good old static compilers (gcc, MSVC, ...) I have
ended up using a struct-based representation.

I remember seeing somewhere that MSVC adds int128, but only for C++ (it is
implemented as a class with operator overloading...). their implementation
is partially based on SIMD intrinsics.


recently, I have ended up adding my own complexes, mostly as MSVC does not
support C99 style complexes (my compiler supports them, however).


I have implemented them mostly with structs.

fcomplex a, b, c, d;

a=fcomplex(1,0);
b=fcomplex(0,1);
c=fcadd(a, b);
d=fcmul(a, b);

there is also dcomplex, and similar 'dc' functions.


my current vector and quat code should also work on gcc and MSVC, but is
currently only "vectorized" for MSVC (since MSVC and GCC don't strictly use
the same vector facilities).

even as such, operations like 'qpow', 'qsin', 'qcos', ... are likely to be
rather slow, although I have not yet benchmarked them (or even verified that
they work...).

as for 'qsin', 'qcos', 'qtan', ... I have implemented these operations (as
per conventional definitions), although I don't know exactly just what they
are supposed to do (and am largely unable to 'visualize' these
operations...).

(my mind seems to partially handle this by using multiple concurrent
'projections' of the space, but this would be further complicated if I were
to plot graphically, since my internal mental projections tend to be full 3D
I think, rather than 2D projections, so I am not the "best" way to project
4D into 2D plots/graphs...).


I could add a "raw" int128 and float128 APIs to C via similar mechanisms,
just it is a question of prefixes.

'dqi' and 'dqf' are possible (slightly less awkward to type than 'i128' and
'f128'...).

dqi128 a, b;

a=dqi128("6942031415926535897932384");
//above: because a string is the only really typable representation I know
of...

b=dqimul(a, a);
....


'dqf' would be about the same, but floating point...


as before, these would probably be good old structs, and probably plain old
C.
(if really needed, I could assembler optimize these though...).

among many other things...
 
J

jacob navia

BGB / cr88192 a écrit :
I use the syntax __int128 and __uint128 personally...

in my compiler, they are also supported by a modified 'inttypes.h', which
defines int128_t and uint128_t (at least for my compiler).

I use just int128. I did the run time all in assembly,
for 32 and 64 bits x86/x64. In x64 I could reuse much
of the 64 bit asm code since as now the registers are
64 bit, the 64 bit data became 128 bit automatically.
it is worth noting that MSVC does not have this header.

Yes, they are not very much int C99.
 
B

BGB / cr88192

jacob navia said:
BGB / cr88192 a écrit :

I use just int128. I did the run time all in assembly,
for 32 and 64 bits x86/x64. In x64 I could reuse much
of the 64 bit asm code since as now the registers are
64 bit, the 64 bit data became 128 bit automatically.

yeah...

in my compiler, it does vaguely similar, but in some cases uses helper
functions (basically, calls into hand-written ASM fragments to do the actual
operations in many cases).


plain 'int128', if built right into the compiler, is a potential conformance
issue, which is partly why I had called it '__int128' in my case (and, as
well, some documentation I ran across mentioned some other compilers using
this type with this name...).

Yes, they are not very much int C99.

yep, I had noticed...


and, on an unrelated note, I am having "fun" hacking a 4D rendering mode
into parts of my 3D engine...

lacking a good name for up/down along the W axis, I ended up overloading
zenith/nadir...
the idea for rendering is that I will just use 4-views 3D projection...

also have slightly hacked over the camera controls, ... as well.

but, this is mostly more of an experiment...

or such...
 
G

gwowen

The regulars said that speaking about 128 bit integers is off topic
since the code doesn't run under gcc, it is specific to lcc-win etc.
They have no clue actually.

Says the man who claims not to indulge in personal attacks.
Seriously, for someone who gets in such a tizzy over supposed
"personal attacks" against you, you do bandy words like "moron"
and "clueless" about with extraordinary frequency.
Certainly more frequently than anyone uses such words about you.
Gcc supports in some platforms 128 bit
integers. The syntax they use is:

GCC supports an extraordianry number of extensions to standard C
(possibly more than LCC-win32). They supported complex numbers
before C99, 80 bit floats on x86, 128 bit floats on x86_64, fixed
point maths, and assortment of guaranteed-atomic data types....

I could go on.

Heres something else I've noticed:

GCC maintainers very rarely post here pretending their
non-standard extensions are part of C. Nor do they suggest
these extensions should be immediately standardised.
Nor do they state people with alternative viewpoints are
morons. Nor do they accuse anyone who disagrees with them
of being "destructive" or indulging in personal attacks.
 
K

Keith Thompson

Richard Heathfield said:
A strictly conforming program is entitled to define its own header
<int128.h> and define its own meaning for int128 (which is in user
namespace) within that header. Your extensions would cause such a
program to become invalid, and therefore your implementation is
non-conforming and thus even more off-topic here than a conforming
implementation would be.

I disagree. A strictly conforming program can't assume that
<int128.h> (as oppposed to "int128.h") is a valid header name.

Providing new functionality in implementation-defined headers is
exactly the right way for a conforming implementation to provide
extensions.

Digressing a bit:

Reading C99 6.10.2, it's not clear to me that implementations
are required to support user-defined headers. #include <foo.h>
searches for a header in "a sequence of implementation-defined
places", which could be controlled entirely by the implementation.
#include "bar.h" includes a source file which is searched for in
implementation-defined manner, but this wording:

If this search is not supported, or if the search fails, the
directive is reprocessed as if it read [#include <bar.h>].

So it seems that an implementation could permit *only* predefined
headers to be included. I doubt that that was the intent.
 
K

Keith Thompson

Scott Fluhrer said:
This doesn't really address your statement, but how often would 128 bit
int's be used anyways? How common is the case where 64 bit int's would be
insufficient, but 128 bits be enough? I suppose it would make keeping a
bitmap of between 65 and 128 bits more convienent, but other than that (at
least for everything else I can think of) if 64 bit int's aren't enough,
then you really need true Bignum's, or at least integers which are
significantly larger (256+ bits).

IPV6 addresses are the only plausible example I can think of. It's
not really necessary to treat them as integers rather than fix-size
byte arrays, but it would probably be convenient in some cases.

Other than that, I suspect 128 bits is well within the range of
diminishing returns, where you might as well just provide arbitarily
wide integers (GMP is one example).

On the other hand, if 128-bit integers are reasonably fast, they
could be a good basis for implementing an arbitrary-width integer
library.
 
J

jacob navia

Scott Fluhrer a écrit :
This doesn't really address your statement, but how often would 128 bit
int's be used anyways?

I did it to satisfy a customer request. As you may know, fixed point
floating point can be implemented using integers. That customer
wanted more precision fixed point calculations.
How common is the case where 64 bit int's would be
insufficient, but 128 bits be enough? I suppose it would make keeping a
bitmap of between 65 and 128 bits more convienent, but other than that (at
least for everything else I can think of) if 64 bit int's aren't enough,
then you really need true Bignum's, or at least integers which are
significantly larger (256+ bits).

lcc-win provides bignums too, but 128 bit integers using 64 bit hardware
is extremely fast in my implementation since the compiler generates
directly the instructions in assembler. For adding a 128 number only
2 instructions are needed... what leaves most bignum implementations
in the dust... far behind.

128 bit UUIDs can be treated as integers using 128 bit instructions.

But sure, its inflation. 15 years ago I was programming in 16 bits.

jacob
 
K

Keith Thompson

jacob navia said:
Scott Fluhrer a écrit :

I did it to satisfy a customer request. As you may know, fixed point
floating point can be implemented using integers. That customer
wanted more precision fixed point calculations.

I think you meant "fixed point real arithmetic".
 
K

Keith Thompson

Richard Heathfield said:
I disagree. The only difference between them is that a quoted header
is first searched for in an implementation-defined manner; if the
search fails (or is not supported), it's just as if < and > were used
instead.
Right.

If your argument is that strictly conforming programs can't
include headers because "How the places are specified or the header
identified is implementation-defined",

No, my argument is that strictly conforming programs can't include
headers other than the standard-defined ones using the said:
then the concept of strict
conformance becomes completely useless because you can't even include
<stdio.h>.

Of course you can (assuming, of course, a hosted implementation).
However the search for <> headers is defined, it must succeed for
And if your argument is *not* that, it's hard to see what
it *is*.

<snip>

My argument is an implementation is not obliged to allow the
programmer to put a header in a place searchable by #include <...>.
A conforming implementation might permit the <> syntax to refer
only to predefined headers. A strictly conforming program may not
assume otherwise.

A strictly conforming program *can* define and use a header that it
refers to using #include "int128.h". (At least I'm sure that's the
intent, though my reading of the standard calls that into some doubt,
as I've just posted in comp.std.c.) For a program that does so,
the directive #include "int128.h" will use the user-defined header,
not lcc-win's implementation-defined header, and all is well.

In essence, headers named by the <> syntax are the implementation's
domain, and headers named by the "" syntax are the programmer's
domain.
 
S

Seebs

I don't agree that the implementation has such power of veto over the
machine, and I'd be interested to see your C&V.

What machine?

I'm not aware of any requirement that the header files exist as files.

7.1.2 is the place to look. Footnote 159 (admittedly non-normative) says:
A header is not necessarily a source file, ...

7.1.2, paragraph 3, also says "If a file with the same name of one of the
above < and > delimited sequences, not provided as part of the implementation,
is placed in any of the standard places that are searched for included source
files, the behavior is undefined."

However, quite simply, there's no requirement that the standard places be
directories which contain files. All that matters is that, if you #include
one of the standard headers, the right declarations come to be in scope.

And no, this is not a purely theoretical issue. I have used compilers
(even ten+ years ago) which used "precompiled headers" that were not C source
files or human-readable.

-s
 
S

Seebs

Right, but <int128.h> is none of the above, which are <assert.h>,
<complex.h>, <ctype.h>, <yadayadayada.h>, and <wctype.h> - i.e. the
standard headers.
Right.
Sure, I know - but that's really beside the point on this occasion. Or
at least, if it isn't beside the point, perhaps you could explain why
it isn't beside the point?

If there's no directory containing files, and the "standard locations"
are internal compiler magic, it is impossible for you to create a file
named 'int128.h' and put it in the standard locations. (Single quotes
used to distinguish from the "" in #include.)

There is never a requirement, given a #include <...> directive, that the
compiler look anywhere or at any file. So if you try to include a header
which isn't one of that list, you're outside the set of things which
have a clearly-defined behavior.

Go back to 6.10.2. "searches a sequence of implementation-defined places for
a header identified by...". Or, more useful, paragraph 1 of 6.10.2:

A #include directive shall identify a header or source file that can
be processed by the implementation.

"Header" and "source file" are two separate categories. <h-char-sequence>
denotes a header, not a source file. "q-char-sequence" denotes a source file.

-s
 
B

BGB / cr88192

Scott Fluhrer said:
This doesn't really address your statement, but how often would 128 bit
int's be used anyways? How common is the case where 64 bit int's would be
insufficient, but 128 bits be enough? I suppose it would make keeping a
bitmap of between 65 and 128 bits more convienent, but other than that (at
least for everything else I can think of) if 64 bit int's aren't enough,
then you really need true Bignum's, or at least integers which are
significantly larger (256+ bits).

the main advantage of 128 bit integers is that they are a lot faster than
generic bignums.
it is also a convinient size to handle in SSE registers, whereas bigger at
present would require a memory-based representation.

granted, there is a cutoff where bignums can become cheaper per-scale than
fixed-size integers, but I suspect it is still a little larger than this.


there are also some things, such as:
GUIDs; IPv6 addresses; ...

which also just happen to be 128 bits...

as well as the possibility of 128 bit DSM pointers, ...


so, they are not useless, just not as useful as some other possible
features.

 
J

jacob navia

BGB / cr88192 a écrit :
the main advantage of 128 bit integers is that they are a lot faster than
generic bignums.
it is also a convinient size to handle in SSE registers, whereas bigger at
present would require a memory-based representation.

I use RDX:RAX register pair. I found that the SSE registers couldn't do
integer operations (even in 64 Bit only) since they somehow are thought
as holding double or floats

How do you use the SSE stuff?
 
R

robertwessel2

This doesn't really address your statement, but how often would 128 bit
int's be used anyways?  How common is the case where 64 bit int's would be
insufficient, but 128 bits be enough?  I suppose it would make keeping a
bitmap of between 65 and 128 bits more convienent, but other than that (at
least for everything else I can think of) if 64 bit int's aren't enough,
then you really need true Bignum's, or at least integers which are
significantly larger (256+ bits).


For folks doing calculations involving currency, 64 bit arithmetic is
inadequate. While 64 bit variables are sufficient to hold almost all
values you'd want to store*, you need longer intermediates**. Since C
doesn't really provide for longer intermediates, a 128 bit type lets
you fake it fairly easily.


*The Cobol standard (and that community is at least serious about
currency) has required the equivalent of 18 decimal digits
(effectively 64 bit binary ints) forever. The most recent Cobol
standards bumped that to 36 digits. And while I'm not sure who has
the most inflated currency at the moment, a favorite example (before
it was devalued) used to be the Turkish Lira - where you could not
represent the GDP of the United States (in TRY) in a 64 bit integer,
so there *have* been semi-reasonable currency related exceptions to
the "64 bits is enough" rule.

**Cobol has always required that some calculations be carried out with
longer intermediates.
 
O

Old Wolf

Now that gcc supports them, (and not only lcc-win)
this will be accepted here I hope...

Huh? Whether or not gcc supports something,
has absolutely no relevance to its topicality.
 
O

Old Wolf

BGB / cr88192 a écrit :

I use just int128.

Did you choose a different name than the standard
one, just to be difficult? This sort of thing is
why people dislike your compiler extensions.
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top