how to implement UINT64 with a U32 compiler

how to implement UINT64 with a U32 compiler

Post by Lian » Sat, 25 Jan 2003 10:59:19



Hi,

I want to define a data type of U64, but the compiler supports max integer
type of U32 only. So how to implement the data type with a U32 compiler?
shall I implement U64 opeations myself, such as multiple, minus, add etc.?
Or is there already such U64 implementation?

Thanks first,
Liang

 
 
 

how to implement UINT64 with a U32 compiler

Post by rjh » Sat, 25 Jan 2003 14:36:13



> Hi,

> I want to define a data type of U64, but the compiler supports max integer
> type of U32 only. So how to implement the data type with a U32 compiler?

I'm tempted to answer "get a better compiler". :-)

Quote:> shall I implement U64 opeations myself, such as multiple, minus, add etc.?

This is certainly possible, although those who actually bother to do this
tend not to stop at 64 bits. (See below.)

Quote:> Or is there already such U64 implementation?

man bc <grin>

Take a look at arbitrary precision packages such as Miracl and GMP. Even if
you end up rolling your own, they will teach you a lot if you let them.

--

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton

 
 
 

how to implement UINT64 with a U32 compiler

Post by Erik de Castro Lop » Sat, 25 Jan 2003 14:42:55



> Hi,

> I want to define a data type of U64, but the compiler supports max integer
> type of U32 only.

Are you sure?

Since you posted this to comp.unix.programmer and gnu.gcc I
suspect that you are using the GNU GCC compiler. If that is
the case, you can use the "long long" type for signed 64 bit
numbers or the "unsigned long long" for unsigned 64 bit
numbers.

Better yet, why not use int64_t and uint64_t as defined
in <stdint.h> and should be avilable on any C99 compiler/
system where 64 bit integers are available.

Erik
--
+-----------------------------------------------------------+

+-----------------------------------------------------------+
"Having a firewall that allows NFS to the Internet is like having a
seat belt that lets your head touch the dashboard." -- Marcus Ranum

 
 
 

how to implement UINT64 with a U32 compiler

Post by Mac » Sat, 25 Jan 2003 15:42:18



> Hi,

> I want to define a data type of U64, but the compiler supports max integer
> type of U32 only. So how to implement the data type with a U32 compiler?
> shall I implement U64 opeations myself, such as multiple, minus, add etc.?
> Or is there already such U64 implementation?

> Thanks first,
> Liang

It may not be what you are looking for, but you can probably find a nice
arbitrary precision math library out there somewhere, too.

--Mac

 
 
 

how to implement UINT64 with a U32 compiler

Post by Rich Tee » Sat, 25 Jan 2003 15:45:59



> I want to define a data type of U64, but the compiler supports max integer
> type of U32 only. So how to implement the data type with a U32 compiler?
> shall I implement U64 opeations myself, such as multiple, minus, add etc.?
> Or is there already such U64 implementation?

Which compiler are you using?  AFAIK, gcc supports the 64-bit
long long, as do many other compilers.

--
Rich Teer

President,
Rite Online Inc.

Voice: +1 (250) 979-1638
URL: http://www.rite-online.net

 
 
 

how to implement UINT64 with a U32 compiler

Post by Maurizio Loret » Sat, 25 Jan 2003 18:25:08




> > I want to define a data type of U64, but the compiler supports max integer
> > type of U32 only. So how to implement the data type with a U32 compiler?
> > shall I implement U64 opeations myself, such as multiple, minus, add etc.?
> > Or is there already such U64 implementation?

> Which compiler are you using?  AFAIK, gcc supports the 64-bit
> long long, as do many other compilers.

They *HAVE* to do so.  long long is *required* by the current C
standard, ISO/IEC 9899-1999; cfr. chapter and verse 6.2.5.4 .

However, the C++ standard (ISO/IEC 14882-1998) does not require a
"long long" integer type...  But compilers that support it for C may
support it also for C++ as an extension.

--
Maurizio Loreti                         http://www.pd.infn.it/~loreti/mlo.html

 
 
 

how to implement UINT64 with a U32 compiler

Post by Dan P » Sat, 25 Jan 2003 22:54:49





>> > I want to define a data type of U64, but the compiler supports max integer
>> > type of U32 only. So how to implement the data type with a U32 compiler?
>> > shall I implement U64 opeations myself, such as multiple, minus, add etc.?
>> > Or is there already such U64 implementation?

>> Which compiler are you using?  AFAIK, gcc supports the 64-bit
>> long long, as do many other compilers.

>They *HAVE* to do so.  long long is *required* by the current C
>standard, ISO/IEC 9899-1999; cfr. chapter and verse 6.2.5.4 .

They have to do so *only* if the claim C99 conformance.  I am aware of
only one such compiler.  All the other compilers support long long as
an extension and they have to diagnose it when invoked in conforming
mode (long long is a syntax error in C89, the standard implemented by
virtually all the C compilers in current use).

Dan
--
Dan Pop
DESY Zeuthen, RZ group

 
 
 

how to implement UINT64 with a U32 compiler

Post by Dan P » Sat, 25 Jan 2003 22:49:02



Quote:>Better yet, why not use int64_t and uint64_t as defined
>in <stdint.h> and should be avilable on any C99 compiler/
>system where 64 bit integers are available.

Because conforming C99 compilers are *very* few and far between.

Dan
--
Dan Pop
DESY Zeuthen, RZ group

 
 
 

how to implement UINT64 with a U32 compiler

Post by Rich Tee » Sun, 26 Jan 2003 02:57:02



Quote:> > Which compiler are you using?  AFAIK, gcc supports the 64-bit
> > long long, as do many other compilers.

> They *HAVE* to do so.  long long is *required* by the current C
> standard, ISO/IEC 9899-1999; cfr. chapter and verse 6.2.5.4 .

<nit pick>
        Only if the compiler wants to claim that it adheres to that
        standard.  My understanding is that gcc has a few gotchas
        of its own...
</nit pick>

--
Rich Teer

President,
Rite Online Inc.

Voice: +1 (250) 979-1638
URL: http://www.rite-online.net

 
 
 

how to implement UINT64 with a U32 compiler

Post by those who know me have no need of my nam » Sun, 26 Jan 2003 03:21:31


netiquette note: a cross-post between these three groups is very unlikely
to be on-topic for all.  also, cross-posts should have a followup-to set.

in comp.unix.programmer i read:

Quote:>I want to define a data type of U64, but the compiler supports max integer
>type of U32 only. So how to implement the data type with a U32 compiler?
>shall I implement U64 opeations myself, such as multiple, minus, add etc.?

learn some math, implement the necessary operations via functions.

Quote:>Or is there already such U64 implementation?

how can we know you didn't name the platform.

--
bringing you boring signatures for 17 years

 
 
 

how to implement UINT64 with a U32 compiler

Post by Dann Corbi » Sun, 26 Jan 2003 03:46:32


"Liang" <leo2002c...@hotmail.com> wrote in message

news:b0q6lo$e3g$1@localhost.localdomain...

> Hi,

> I want to define a data type of U64, but the compiler supports max integer
> type of U32 only. So how to implement the data type with a U32 compiler?
> shall I implement U64 opeations myself, such as multiple, minus, add etc.?
> Or is there already such U64 implementation?

If you want to implement a data type with normal integral operators, you
will have to use C++.  Otherwise, you will be forced to do this:
    foo = add64(a, b);
instead of:
    foo = a + b;

<tragically_off_topic>
Here is some stuff I made from a start I found on the net somewhere.  I
found another solution and never used it, so it is largely untested.
Original author unknown:

#include <assert.h>
#include <string.h>
#include <math.h>
#include <string.h>
#include <errno.h>

#include "c64i.hpp"

// The most significant bit of a signed long.
static const long msb32 = 0x80000000;

//-------------------------------------------------------------------------
// Constructors
i64_t::i64_t(): high_part(0), low_part(0){}

//-------------------------------------------------------------------------
i64_t::i64_t(long lo,  long hi):high_part(hi),low_part(lo){}

//-------------------------------------------------------------------------
i64_t::i64_t(const i64_t
&other):high_part(other.high_part),low_part(other.low_part){}

//-------------------------------------------------------------------------
i64_t
&i64_t::operator=(const i64_t &other)
{
  if(this != &other) {
    high_part = other.high_part;
    low_part = other.low_part;
  };
  return *this;

}

//-------------------------------------------------------------------------
// Destructor
i64_t::~i64_t(){}

//-------------------------------------------------------------------------
bool
i64_t::operator==(const i64_t &rhs) const
{
  return (high_part == rhs.high_part && low_part == rhs.low_part);

}

//-------------------------------------------------------------------------
bool
i64_t::operator>=(const i64_t &rhs) const
{
  if(high_part > rhs.high_part) {
    return true;
  }
  if(high_part < rhs.high_part) {
    return false;
  }
  return (low_part >= rhs.low_part);

}

//-------------------------------------------------------------------------
bool
i64_t::operator!=(const i64_t &rhs) const
{
  return (!(*this == rhs));

}

//-------------------------------------------------------------------------
bool
i64_t::operator<=(const i64_t &rhs) const
{
  return (*this == rhs || !(*this >= rhs));

}

//-------------------------------------------------------------------------
bool
i64_t::operator<(const i64_t &rhs) const
{
  return (!(*this >= rhs));

}

//-------------------------------------------------------------------------
bool
i64_t::operator>(const i64_t &rhs) const
{
  return (!(*this <= rhs));

}

//-------------------------------------------------------------------------
i64_t
&i64_t::operator+=(const i64_t &rhs)
{
  high_part += rhs.high_part;
  if ((long)low_part < 0 && (long)(rhs.low_part) < 0) {
    low_part += rhs.low_part;
    high_part++;
  } else if ((long)low_part < 0 || (long)(rhs.low_part) < 0) {
    low_part += rhs.low_part;
    if ((long)low_part >= 0) high_part++;
  } else {
    low_part += rhs.low_part;
  };
  return *this;

}

//-------------------------------------------------------------------------
i64_t
&i64_t::operator-=(const i64_t &rhs)
{
  high_part += ~rhs.high_part;
  if ((long)low_part < 0 || (long)(~rhs.low_part) < 0) {
    low_part += ~rhs.low_part;
    high_part++;
  } else if ((long)low_part < 0 || (long)(~rhs.low_part) < 0) {
    low_part += ~rhs.low_part;
    if ((long)low_part >= 0) high_part++;
  } else {
    low_part += ~rhs.low_part;
  };
  return *this;

}

//-------------------------------------------------------------------------
i64_t
i64_t::operator+(const i64_t &rhs) const
{
  // Value to return.
  long retHi;
  long retLo;

  // Add the low word.
  retLo = low_part + rhs.low_part;

  // Add the high word.
  retHi = high_part + rhs.high_part;
  // Check for carry from low word.
  if (((low_part & msb32) && (rhs.low_part & msb32)) ||
      (((low_part & msb32) || (rhs.low_part & msb32)) && !(retLo & msb32)))
{
    retHi++;
  };

  return i64_t(retLo,retHi);

}

//-------------------------------------------------------------------------
i64_t
i64_t::operator+(const signed long &rhs) const
{
  // Value to return.
  long retHi;
  long retLo;

  //Only implemented for positive arguments currently
  if (rhs<0) assert(false);

  // Add the low word.
  retLo = low_part + rhs;
  //Copy the high word
  retHi = high_part;

  // Check for carry from low word.
  if (((low_part & msb32) && (rhs & msb32)) ||
      (((low_part & msb32) || (rhs & msb32)) && !(retLo & msb32))) {
    retHi++;
  };

  return i64_t(retLo,retHi);

}

//-------------------------------------------------------------------------
i64_t
&i64_t::operator++()
{
  if(low_part == 0xFFFFFFFF) {
    low_part = 0;
    high_part++;
  }
  else {
    low_part++;
  }

  return *this;

}

//-------------------------------------------------------------------------
i64_t
i64_t::operator++(int)
{
  // The value upon entering (to return).
  long beforeLo(low_part);
  long beforeHi(high_part);

  if(low_part == 0xFFFFFFFF) {
    low_part = 0;
    high_part++;
  }
  else {
    low_part++;
  }

  return i64_t(beforeLo,beforeHi);

}

//-------------------------------------------------------------------------
i64_t
&i64_t::operator--()
{
  if(low_part == 0) {
    low_part = 0xFFFFFFFF;
    high_part--;
  }
  else {
    low_part--;
  }

  return *this;

}

//-------------------------------------------------------------------------
i64_t
i64_t::operator--(int)
{
  // The value upon entering (to return).
  long beforeLo(low_part);
  long beforeHi(high_part);

  if(low_part == 0) {
    low_part = 0xFFFFFFFF;
    high_part--;
  }
  else {
    low_part--;
  }

  return i64_t(beforeLo,beforeHi);

}

//-------------------------------------------------------------------------
i64_t
i64_t::operator<<(const unsigned long &rhs) const
{
  // The return value.
  long retHi;
  long retLo;

  if(rhs >= 64) {
    retLo = 0;
    retHi = 0;
  }
  else if(rhs == 0) {
    retLo = low_part;
    retHi = high_part;
  }
  else if(rhs < 32) {
    retLo = low_part << rhs;
    retHi = (high_part << rhs) | (low_part >> (32 - rhs));
  }
  else {
    retLo = 0;
    retHi = low_part << (rhs - 32);
  }

  return i64_t(retLo,retHi);

}

//-------------------------------------------------------------------------
i64_t
i64_t::operator>>(const unsigned long &rhs) const
{
  // The return value.
  long retHi;
  long retLo;

  if(rhs >= 64) {
    retLo = 0;
    retHi = 0;
  }
  else if(rhs == 0) {
    retLo = low_part;
    retHi = high_part;
  }
  else if(rhs < 32) {
    retLo = (high_part << (32 - rhs)) | (low_part >> rhs);
    retHi = high_part >> rhs;
  }
  else {
    retLo = high_part >> (rhs - 32);
    retHi = 0;
  }

  return i64_t(retLo,retHi);

}

//-------------------------------------------------------------------------
i64_t
i64_t::operator~() const
{
  return i64_t(~low_part,~high_part);

}

//-------------------------------------------------------------------------
i64_t
i64_t::operator&(
  const i64_t &rhs
) const
{
  return i64_t(low_part & rhs.low_part,high_part & rhs.high_part);

}

//-------------------------------------------------------------------------
i64_t
i64_t::operator|(
  const i64_t &rhs
) const
{
  return i64_t(low_part | rhs.low_part,high_part | rhs.high_part);

}

//-------------------------------------------------------------------------
const long&
i64_t::low() const
{
  return low_part;

}

//-------------------------------------------------------------------------
const long&
i64_t::high() const
{
  return high_part;

}

Include file:

// For some lame systems that have no 64 bit i64_t type at all, we can do
some
// elementary math and bitwise operations on a class and have it look the
same
// everywhere...

#undef i64_t

class i64_t {
  public:

    // make 64 bit integer. Initiallly set to zero.
    i64_t();

    // make 64 bit integer from two 32 bit integers.
    i64_t(long lo, long hi=0);

    // make 64 bit integer from another.
    i64_t(const i64_t &other);

    i64_t &operator=(const i64_t &other);

    // Destructor

    ~i64_t();

    // operators

    bool operator==(const i64_t &rhs) const;

    bool operator>=(const i64_t &rhs) const;

    bool operator!=(const i64_t &rhs) const;

    bool operator<=(const i64_t &rhs) const;

    bool operator<(const i64_t &rhs) const;

    bool operator>(const i64_t &rhs) const;

    i64_t &operator+=(const i64_t &rhs);

    i64_t &operator-=(const i64_t &rhs);

    i64_t operator+(const i64_t &rhs) const;

    i64_t operator+(const signed long &rhs) const;

    i64_t &operator++();

    i64_t operator++(int idum);

    i64_t &operator--();

    i64_t operator--(int idum);

    i64_t operator<<(const unsigned long &rhs) const;

    i64_t operator>>(const unsigned long &rhs) const;

    i64_t operator~() const;

    i64_t operator&(const i64_t &rhs) const;

    i64_t operator|(const i64_t &rhs) const;

    const long& low() const;

    const long& high() const;

  private:
    long low_part;
    long high_part;

};

</tragically_off_topic>
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 "The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm
 
 
 

how to implement UINT64 with a U32 compiler

Post by Lian » Sun, 26 Jan 2003 16:43:50


Yes, it's not as powerful as gcc, so no 'long long' type.




> > Hi,

> > I want to define a data type of U64, but the compiler supports max
integer
> > type of U32 only.

> Are you sure?

> Since you posted this to comp.unix.programmer and gnu.gcc I
> suspect that you are using the GNU GCC compiler. If that is
> the case, you can use the "long long" type for signed 64 bit
> numbers or the "unsigned long long" for unsigned 64 bit
> numbers.

> Better yet, why not use int64_t and uint64_t as defined
> in <stdint.h> and should be avilable on any C99 compiler/
> system where 64 bit integers are available.

> Erik
> --
> +-----------------------------------------------------------+

> +-----------------------------------------------------------+
> "Having a firewall that allows NFS to the Internet is like having a
> seat belt that lets your head touch the dashboard." -- Marcus Ranum

 
 
 

how to implement UINT64 with a U32 compiler

Post by Bjorn Rees » Sun, 26 Jan 2003 21:53:46




> >Better yet, why not use int64_t and uint64_t as defined
> >in <stdint.h> and should be avilable on any C99 compiler/
> >system where 64 bit integers are available.

> Because conforming C99 compilers are *very* few and far between.

And even a C99 compiler is not required to offer the int64_t
and uint64_t types.
 
 
 

how to implement UINT64 with a U32 compiler

Post by Jack Klei » Mon, 27 Jan 2003 12:49:51


On Sat, 25 Jan 2003 12:53:46 +0000, Bjorn Reese



> > >Better yet, why not use int64_t and uint64_t as defined
> > >in <stdint.h> and should be avilable on any C99 compiler/
> > >system where 64 bit integers are available.

> > Because conforming C99 compilers are *very* few and far between.

> And even a C99 compiler is not required to offer the int64_t
> and uint64_t types.

True, but extremely misleading.

If a c99 compiler has a 2's complement signed type of exactly 64 bits
(1 sign, 63 value) then it is required to provide int64_t.

Likewise if a c99 compiler has an unsigned integer type of exactly 64
value bits, it is required to provide uint64_t.

The word "offer" makes it sound like an implementation's decision,
when it is not.  If signed and unsigned long long meet the
characteristics above, the implementation is required to provide the
exact sized typedefs.

I suppose that an implementation could manage to avoid providing these
typedefs if it could manage to provide all the integer types,
including signed and unsigned long long, without any of them fitting
the requirements, even if the hardware supports these types directly,
but that would be suicidal from a QOI point of view.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

 
 
 

how to implement UINT64 with a U32 compiler

Post by E. Gibbo » Mon, 27 Jan 2003 13:35:17




>On Sat, 25 Jan 2003 12:53:46 +0000, Bjorn Reese



>> > >Better yet, why not use int64_t and uint64_t as defined
>> > >in <stdint.h> and should be avilable on any C99 compiler/
>> > >system where 64 bit integers are available.

>> > Because conforming C99 compilers are *very* few and far between.

>> And even a C99 compiler is not required to offer the int64_t
>> and uint64_t types.

>True, but extremely misleading.

>If a c99 compiler has a 2's complement signed type of exactly 64 bits
>(1 sign, 63 value) then it is required to provide int64_t.

>Likewise if a c99 compiler has an unsigned integer type of exactly 64
>value bits, it is required to provide uint64_t.

>The word "offer" makes it sound like an implementation's decision,
>when it is not.  If signed and unsigned long long meet the
>characteristics above, the implementation is required to provide the
>exact sized typedefs.

>I suppose that an implementation could manage to avoid providing these
>typedefs if it could manage to provide all the integer types,
>including signed and unsigned long long, without any of them fitting
>the requirements, even if the hardware supports these types directly,
>but that would be suicidal from a QOI point of view.

...Or the implementation might consist of a trivial or "shallow" port of a
32-bit C99 compiler to 64-bit hardware (i.e., using software and
operations on 4 bytes to implement long long, ignoring the hardware's
ability to directly handle 8 byte ints).  There might be reasons, beyond
simple laziness, to want such a thing: binary compatibility with existing
object files, re-use of a tested and trusted (32-bit) code generator,
etc..  Obviously, this would be wasting much of the capabilities of the
64-bit hardware, but protecting an existing software investment is an
important component of "QoI" to many -- and look how long Windows users
were happy with 16-bit code, running on 32-bit machines.  Indeed, I
wouldn't be surprised if similar inept stumbling issues from the same
quarter of the industry on the 32-to-64-bit transition.

--Ben
--

 
 
 

1. Q: Is the C++ STL now fully implemented in a Linux compiler?

Hello.

I am interested in learning to program Linux apps, and wonder if, since
the STL was just finalized this year, if the compiler libraries have
been updated.

Thanks in advance,

Robert
"Fall down seven times, get up eight." -- Buddhist quote
( email return address is spam resistant )

2. IDE controller on new Dell Dimension 4500?

3. CBQ and u32 filter

4. CUPS from remote computer

5. CBQ With U32 Classifier: Please Help

6. mdrecoveryd?

7. tc + u32 classifier. Help needed!

8. restore /proc/ksyms

9. radeonfb aggregated LY/LZ 8MB + ia64 void * vs u32

10. Port Prioritisation with U32 class

11. --u32 Filter doesn't work

12. "iptables mark with filter fw" vs "u32 match"

13. tc filter u32 match src !ip