2

I have the following code...

            ran_int = rand(); //check READ ME Citation B
            if (input == 32){
                //rand() with 2^31 as lower limit and 2^32 as its upper
                long long int upper_limit = 4294967295;
                long long int lower_limit = 2147483649
                ran_32_64 = (rand() * 2) % (upper_limit - lower_limit);
                ran_32_64 += lower_limit;
            }
            else if(input == 64){
                //rand() x 4 with 2^63 as lower limit and 2^64 as its upper
                unsigned long long int upper_limit = powl(2, 64);
                long long int lower_limit = powl(2, 63); 
                ran_32_64 = (rand() * 4) % (upper_limit - lower_limit); 
                ran_32_64 += lower_limit;

            }
            else if(input == 128){
                //rand() x 8 with 2^127 as lower limit
                unsigned _int128 upper_limit = 
            }

and for the last block I need to represent a 128 bit binary number. I know I can use the type _int128 for 128 bit values, but that's not totally precise.

So I'm thinking to be totally precise I could use type double, but I can't find any literature on 128 bit double types.

Any ideas?

Kendall Weihe
  • 111
  • 1
  • 1
  • 9
  • You should do some research on floating point numbers. Actually, integers **are** precise, while floating point is **not**! And `_int128` is no standard type anyway. – too honest for this site Nov 07 '15 at 15:47
  • 1
    The sizes, ranges and representations of the numeric types in C depends on the platform; presumably your platform does not offer a 128-bit floating point type. – Kerrek SB Nov 07 '15 at 15:47
  • 1
    The result of `unsigned long long int upper_limit = powl(2, 64);` won't fit a 64-bit unsigned variable. You'll need a 128-bit variable to store it. – Weather Vane Nov 07 '15 at 15:53
  • if you're trying to do integer powers of 2, you can just use the left shift operator. Make sure you don't right shift it by the width of its type or more, though. – Bobby Sacamano Nov 07 '15 at 17:07
  • instead of `powl(2, 63)`, use `1LL << 63` instead. `powl(2, 64)` should be `__int128(1) << 64` – phuclv Jul 27 '17 at 04:37

1 Answers1

5

Compiler support

It's not a double if it is 128b, but both GNU and Intel C/C++ compilers support 128b floats via __float128 (older Intel C/C++ compilers had Quad) instead.

The GCC documentation is quite thorough.

Library support

There are library implementations including:

Modified code

It is hard to tell what your code is trying to do, but the 128-bit integer equivalent of what you wrote before is below.

I honestly don't know where you intend to use floating-point numbers of any width, so please provide a more appropriate example if you want details for 128b floats.

#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#include <quadmath.h>

void foo(int input) {
    int ran_int = rand(); //check READ ME Citation B
    if (input == 32){
        //rand() with 2^31 as lower limit and 2^32 as its upper
        uint32_t upper_limit = 4294967295;
        int32_t  lower_limit = 2147483649;
        uint32_t ran_32_64 = (rand() * 2) % (upper_limit - lower_limit);
        ran_32_64 += lower_limit;
    }
    /*
    else if(input == 64){
        //rand() x 4 with 2^63 as lower limit and 2^64 as its upper
        uint64_t upper_limit = powl(2L, 64);
        int64_t  lower_limit = powl(2L, 63);
        uint64_t ran_32_64 = (rand() * 4) % (upper_limit - lower_limit);
        ran_32_64 += lower_limit;

    }
    */
    else if(input == 128){
        //rand() x 8 with 2^127 as lower limit
        unsigned __int128 upper_limit = powq(2, 64);
        __int128  lower_limit = powq(2, 63);
        unsigned __int128 ran_32_64 = (rand() * 4) % (upper_limit - lower_limit);
        ran_32_64 += lower_limit;
    }
}
Jeff Hammond
  • 5,374
  • 3
  • 28
  • 45