F
Francois Grieu
[reposted with tweaks, and code that compiles]
Assume a conforming C99 implementation that defines __STDC_IEC_559__.
"double" is a floating point type capable of exactly representing all
integers in the range [0..0x1FFFFFFFFFFFFF] (that's 53 bit). Also assume
FE_TONEAREST is in effect.
Can it be said that multiplication and division of double are exactly
defined? Or/and that when x and y are in range [0..0x1FFFFFFFFFFFFF],
the result of the following functions mym() and myd() is fully specified ?
Note: that would seem to imply over 105 bits of internal precision on
intermediary results before the rounding occurs.
TIA,
Francois Grieu
#include <stdlib.h>
#include <math.h>
#include <fenv.h>
#include <stdio.h>
#ifndef __STDC_IEC_559__
// #error "No claim IEC 60559 FP is available"
#endif
#ifndef FE_TONEAREST
#error "error: FE_TONEAREST is not available"
#endif
typedef unsigned long long tu53;
// question: is that portable?
// it would imply implies a 106-bit wide multiplier output
tu53 mym(tu53 x, tu53 y)
{
return llrint( ( ((double)1/(1ull<<53)) * x ) * y );
}
// question: is that portable?
// it would imply implies a 106-bit wide multiplier output
tu53 myd(tu53 x, tu53 y)
{
return y > x ? llrint( ( (double)(1ull<<53) * x ) / y ) : 0;
}
tu53 myatou53(const char *inStr)
{
long long x;
return inStr!=NULL && (x = atoll(inStr))>=0 && x<1ull<<53 ? x : 0;
}
// for each pair of arguments x y, sghow x y mym(x,y) myd(x,y)
int main(int argc, char *argv[])
{
int j;
if (fesetround(FE_TONEAREST)==0)
for( j=2; j<argc; j+= 2 )
{
tu53 x,y;
x = myatou53(argv[j-1]);
y = myatou53(argv[j]);
// <OT> if that does not work under Win32, change ll to I64 </OT>
printf("#\t%llu\t%llu\t%llu\t%llu\n",
x, y, mym(x,y), myd(x,y) );
}
return EXIT_SUCCESS;
}
Assume a conforming C99 implementation that defines __STDC_IEC_559__.
"double" is a floating point type capable of exactly representing all
integers in the range [0..0x1FFFFFFFFFFFFF] (that's 53 bit). Also assume
FE_TONEAREST is in effect.
Can it be said that multiplication and division of double are exactly
defined? Or/and that when x and y are in range [0..0x1FFFFFFFFFFFFF],
the result of the following functions mym() and myd() is fully specified ?
Note: that would seem to imply over 105 bits of internal precision on
intermediary results before the rounding occurs.
TIA,
Francois Grieu
#include <stdlib.h>
#include <math.h>
#include <fenv.h>
#include <stdio.h>
#ifndef __STDC_IEC_559__
// #error "No claim IEC 60559 FP is available"
#endif
#ifndef FE_TONEAREST
#error "error: FE_TONEAREST is not available"
#endif
typedef unsigned long long tu53;
// question: is that portable?
// it would imply implies a 106-bit wide multiplier output
tu53 mym(tu53 x, tu53 y)
{
return llrint( ( ((double)1/(1ull<<53)) * x ) * y );
}
// question: is that portable?
// it would imply implies a 106-bit wide multiplier output
tu53 myd(tu53 x, tu53 y)
{
return y > x ? llrint( ( (double)(1ull<<53) * x ) / y ) : 0;
}
tu53 myatou53(const char *inStr)
{
long long x;
return inStr!=NULL && (x = atoll(inStr))>=0 && x<1ull<<53 ? x : 0;
}
// for each pair of arguments x y, sghow x y mym(x,y) myd(x,y)
int main(int argc, char *argv[])
{
int j;
if (fesetround(FE_TONEAREST)==0)
for( j=2; j<argc; j+= 2 )
{
tu53 x,y;
x = myatou53(argv[j-1]);
y = myatou53(argv[j]);
// <OT> if that does not work under Win32, change ll to I64 </OT>
printf("#\t%llu\t%llu\t%llu\t%llu\n",
x, y, mym(x,y), myd(x,y) );
}
return EXIT_SUCCESS;
}