Re: Fractional part of decimal value.
"Richard A. O'Keefe" <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
On 8/08/2013, at 2:14 AM, Wouter Beek wrote:
> Hi all,
>
> I want to extract the integer and fractional part of a decimal value:
Um, SWI Prolog doesn't *HAVE* decimal values.
It has exact integers, exact rational numbers, and
*BINARY* floating point numbers.
> ~~~{.pl}
> decimal_parts(D, I, F):-
> I is floor(D / 1),
> F is D - I * 1.
The name of your predicate is at best misleading.
It has nothing to do with "decimal".
Why floor(D/1) rather than floor(D)?
In any case the "integer part" of a floating-point number
is usually understood to be what you get by *truncation*,
not flooring: the integer part of -2.5 is -2, not -3.
For example, the C functions modff(), modf(), modfl():
"These functions break the argument x into integral and
fractional parts, each of which has the same sign as
the argument."
Why I*1 rather than I?
float_parts(Float, Integer_Part, Fraction_Part) :-
Integer_Part is truncate(Float),
Fraction_Part is Float - Integer_Part.
> ~~~
> What I get is the fractional part of the float value 1.1:
> ~~~
> ?- decimal_parts(1.1, _, F).
> F = 0.10000000000000009.
Yep, that looks right.
m% cat >part.c
#include <math.h>
#include <stdio.h>
int main(void) {
double x = 1.1;
double i;
double f = modf(x, &i);
printf("%.16e = %.16e + %.16e\n", x, i, f);
return 0;
}
m% cc part.c -lm
m% a.out
1.1000000000000001e+00 = 1.0000000000000000e+00 + 1.0000000000000009e-01
> ~~~
> I do not mind the padding zero's (just a notational difference), but I do
> not need the 9 at the end.
>
> Is there a way to get the same result as with e.g. C's modf (sample code
> below)? Thanks for any suggestions!
You ***DID*** get the same result as C's modf().
When you wrote your sample C code you forgot to make printf()
print enough digits for the 9 to show up. The sole difference
between C and SWI Prolog here is that SWI Prolog did not lie to you.
You may not "need the 9 at the end" but in the machine's floating point
arithmetic the 9 is *THERE*.