Re: What is a concise way to test if floating point value is integral?

2013-08-29 Thread Paul Jurczak

On Thursday, 29 August 2013 at 05:47:43 UTC, Paul Jurczak wrote:

I'm writing this rather ugly:

sqrt(cast(float)D) != round(sqrt(cast(float)D)

line and I'm looking for more concise notation without 
introducing a meaningless variable to hold expression being 
tested. Is there an equivalent of std.math.trunc(), which would 
return fractional portion instead, maybe frac()?


I defined a helper function:

bool isIntegral(T)(T x) {return x == round(x);}

but is there something in D libraries to give me this 
functionality?


Re: What is a concise way to test if floating point value is integral?

2013-08-29 Thread Jonathan M Davis
On Thursday, August 29, 2013 07:47:16 Paul Jurczak wrote:
 I'm writing this rather ugly:
 
 sqrt(cast(float)D) != round(sqrt(cast(float)D)
 
 line and I'm looking for more concise notation without
 introducing a meaningless variable to hold expression being
 tested. Is there an equivalent of std.math.trunc(), which would
 return fractional portion instead, maybe frac()?

There may be something in std.math which makes it cleaner, but I would have 
thought that the to test whether a floating point value is an integral value, 
you'd just cast it to an integral type and then compare that against the 
original. e.g.

auto isIntegral = cast(int)my_float == my_float;

- Jonathan M Davis


Re: What is a concise way to test if floating point value is integral?

2013-08-29 Thread Paul Jurczak
On Thursday, 29 August 2013 at 06:23:18 UTC, Jonathan M Davis 
wrote:

On Thursday, August 29, 2013 07:47:16 Paul Jurczak wrote:

I'm writing this rather ugly:

sqrt(cast(float)D) != round(sqrt(cast(float)D)

line and I'm looking for more concise notation without
introducing a meaningless variable to hold expression being
tested. Is there an equivalent of std.math.trunc(), which would
return fractional portion instead, maybe frac()?


There may be something in std.math which makes it cleaner, but 
I would have
thought that the to test whether a floating point value is an 
integral value,
you'd just cast it to an integral type and then compare that 
against the

original. e.g.

auto isIntegral = cast(int)my_float == my_float;

- Jonathan M Davis


Isn't type conversion:

auto isIntegral = to!int(my_float) == my_float;

more recommended/idiomatic D way to deal with built-in types?


Re: What is a concise way to test if floating point value is integral?

2013-08-29 Thread Jonathan M Davis
On Thursday, August 29, 2013 08:50:47 Paul Jurczak wrote:
 On Thursday, 29 August 2013 at 06:23:18 UTC, Jonathan M Davis
 
 wrote:
  On Thursday, August 29, 2013 07:47:16 Paul Jurczak wrote:
  I'm writing this rather ugly:
  
  sqrt(cast(float)D) != round(sqrt(cast(float)D)
  
  line and I'm looking for more concise notation without
  introducing a meaningless variable to hold expression being
  tested. Is there an equivalent of std.math.trunc(), which would
  return fractional portion instead, maybe frac()?
  
  There may be something in std.math which makes it cleaner, but
  I would have
  thought that the to test whether a floating point value is an
  integral value,
  you'd just cast it to an integral type and then compare that
  against the
  original. e.g.
  
  auto isIntegral = cast(int)my_float == my_float;
  
  - Jonathan M Davis
 
 Isn't type conversion:
 
 auto isIntegral = to!int(my_float) == my_float;
 
 more recommended/idiomatic D way to deal with built-in types?

Not really IMHO. std.conv.to does fancier conversions than casting does, and 
it throws in cases of overflow, neither of which are of any benefit when 
converting a float to an int, as any integral value in a float will fit in an 
int. Using to would just create extra overhead for no extra benefit in this 
case.

- Jonathan M Davis


Re: What is a concise way to test if floating point value is integral?

2013-08-29 Thread Paul Jurczak
On Thursday, 29 August 2013 at 07:51:40 UTC, Jonathan M Davis 
wrote:

[..]

as any integral value in a float will fit in an
int.

[..]

Will it? Most of them will not fit, but cast to int produces 
nonsensical value anyway as in this example:


cast(int)float.max

With to!int you get a proper warning.


Re: What is a concise way to test if floating point value is integral?

2013-08-29 Thread Jonathan M Davis
On Thursday, August 29, 2013 10:07:31 Paul Jurczak wrote:
 On Thursday, 29 August 2013 at 07:51:40 UTC, Jonathan M Davis
 wrote:
 [..]
 
  as any integral value in a float will fit in an
  int.
 
 [..]
 
 Will it? Most of them will not fit

Sure, they will. float has 32 bits, just like int, so it can't possibly hold a 
value larger than an int can hold. This code passes with flying colors

foreach(i; int.min .. int.max)
assert(cast(float)i == i);

 but cast to int produces
 nonsensical value anyway as in this example:
 
 cast(int)float.max

So what? All you care about here is whether the value in the float is an 
integral value. float.max isn't an integral value, so it really doesn't matter 
if you get overflow when converting. It would have to convert back to the exact 
same value when converting it back to a float, and it won't.

assert(cast(int)float.max == float.max);

will fail. It might make more sense to use to!int if you want to use the 
resulting int for something, but all you're doing with it is comparing it 
against the original float to see if it's the same value. If anything, the fact 
that to!int throws would be a serious problem for what you're trying to do, 
because if what you're testing for is whether a float holds an integral value, 
throwing on overflow when converting to int would just get in your way. It 
should just result in false in that case (because it's not an integral value, 
or it wouldn't overflow), and the cast will result in false, unlike to!int.

- Jonathan M Davis


Re: What is a concise way to test if floating point value is integral?

2013-08-29 Thread Paul Jurczak
On Thursday, 29 August 2013 at 08:26:11 UTC, Jonathan M Davis 
wrote:

On Thursday, August 29, 2013 10:07:31 Paul Jurczak wrote:

On Thursday, 29 August 2013 at 07:51:40 UTC, Jonathan M Davis
wrote:
[..]

 as any integral value in a float will fit in an
 int.

[..]

Will it? Most of them will not fit


Sure, they will. float has 32 bits, just like int, so it can't 
possibly hold a
value larger than an int can hold. This code passes with flying 
colors


foreach(i; int.min .. int.max)
assert(cast(float)i == i);


but cast to int produces
nonsensical value anyway as in this example:

cast(int)float.max


So what? All you care about here is whether the value in the 
float is an
integral value. float.max isn't an integral value, so it really 
doesn't matter
if you get overflow when converting. It would have to convert 
back to the exact

same value when converting it back to a float, and it won't.

assert(cast(int)float.max == float.max);

will fail. It might make more sense to use to!int if you want 
to use the
resulting int for something, but all you're doing with it is 
comparing it
against the original float to see if it's the same value. If 
anything, the fact
that to!int throws would be a serious problem for what you're 
trying to do,
because if what you're testing for is whether a float holds an 
integral value,
throwing on overflow when converting to int would just get in 
your way. It
should just result in false in that case (because it's not an 
integral value,
or it wouldn't overflow), and the cast will result in false, 
unlike to!int.


- Jonathan M Davis


I should have used integer instead of integral to avoid math 
vs. programming language confusion.


Well, float.max is an integer number! Its value is 3.40282e+38. 
The function I defined at the top of this page:


bool isIntegral(T)(T x) {return x == round(x);}

works correctly with float.max. Using cast(int) fails. I should 
have written it as:


bool isInteger(T)(T x) {return x == round(x);}



Re: What is a concise way to test if floating point value is integral?

2013-08-29 Thread anonymous
On Thursday, 29 August 2013 at 08:26:11 UTC, Jonathan M Davis 
wrote:

On Thursday, August 29, 2013 10:07:31 Paul Jurczak wrote:

On Thursday, 29 August 2013 at 07:51:40 UTC, Jonathan M Davis
wrote:
[..]

 as any integral value in a float will fit in an
 int.

[..]

Will it? Most of them will not fit


Sure, they will. float has 32 bits, just like int, so it can't 
possibly hold a

value larger than an int can hold.


float can't hold more distinct values than int, but a float can 
have integer values greater than int.max. (Also, there are int 
values that a float cannot store.)



This code passes with flying colors

foreach(i; int.min .. int.max)
assert(cast(float)i == i);


That's because both sides are casted to float.

[...]

float.max isn't an integral value,


It's not a value that an int can store, but it's an integer in 
the mathematical sense.


Re: What is a concise way to test if floating point value is integral?

2013-08-29 Thread JS

On Thursday, 29 August 2013 at 08:58:02 UTC, Paul Jurczak wrote:
On Thursday, 29 August 2013 at 08:26:11 UTC, Jonathan M Davis 
wrote:

On Thursday, August 29, 2013 10:07:31 Paul Jurczak wrote:

On Thursday, 29 August 2013 at 07:51:40 UTC, Jonathan M Davis
wrote:
[..]

 as any integral value in a float will fit in an
 int.

[..]

Will it? Most of them will not fit


Sure, they will. float has 32 bits, just like int, so it can't 
possibly hold a
value larger than an int can hold. This code passes with 
flying colors


   foreach(i; int.min .. int.max)
   assert(cast(float)i == i);


but cast to int produces
nonsensical value anyway as in this example:

cast(int)float.max


So what? All you care about here is whether the value in the 
float is an
integral value. float.max isn't an integral value, so it 
really doesn't matter
if you get overflow when converting. It would have to convert 
back to the exact

same value when converting it back to a float, and it won't.

assert(cast(int)float.max == float.max);

will fail. It might make more sense to use to!int if you want 
to use the
resulting int for something, but all you're doing with it is 
comparing it
against the original float to see if it's the same value. If 
anything, the fact
that to!int throws would be a serious problem for what you're 
trying to do,
because if what you're testing for is whether a float holds an 
integral value,
throwing on overflow when converting to int would just get in 
your way. It
should just result in false in that case (because it's not an 
integral value,
or it wouldn't overflow), and the cast will result in false, 
unlike to!int.


- Jonathan M Davis


I should have used integer instead of integral to avoid 
math vs. programming language confusion.


Well, float.max is an integer number! Its value is 3.40282e+38. 
The function I defined at the top of this page:


bool isIntegral(T)(T x) {return x == round(x);}

works correctly with float.max. Using cast(int) fails. I should 
have written it as:


bool isInteger(T)(T x) {return x == round(x);}


Yes, casting will not work because a float type can't be fully 
cast to an int without possible overflow.


Your method works fine. The only issue, the issue with comparing 
any floating point, is tolerance. How close to an int does a 
float have to be to be considered an int?


If you can afford to do something like `return (abs(x - round(x)) 
 tol)`.


(remember, numerical computations can result in floating point 
numbers that are suppose be integers but are not(accumulation of 
rounding errors). Using == results in using the tolerance of a 
float, its minimum value)




Also look at FXTRACT.


Re: What is a concise way to test if floating point value is integral?

2013-08-29 Thread Simen Kjaeraas

On 2013-08-29, 10:25, Jonathan M Davis wrote:


On Thursday, August 29, 2013 10:07:31 Paul Jurczak wrote:

On Thursday, 29 August 2013 at 07:51:40 UTC, Jonathan M Davis
wrote:
[..]

 as any integral value in a float will fit in an
 int.

[..]

Will it? Most of them will not fit


Sure, they will. float has 32 bits, just like int, so it can't possibly  
hold a

value larger than an int can hold. This code passes with flying colors

foreach(i; int.min .. int.max)
assert(cast(float)i == i);


First, that's showing the exact opposite of what you're saying it does.
Second, it doesn't even show that.

Your code is equivalent to:

foreach(i; int.min .. int.max)
assert(cast(float)i == cast(float)i);

If that does not pass with flying colors, I'd be surprised. Now try this:

foreach(i; int.min .. int.max) {
float f = i; // DMD optimizes out cast(int)cast(float)int
assert(cast(int)f == i);
}

It will fail for odd numbers in the range 16,777,216-33,554,432, and for
numbers not divisible by 4 in the range to the next power of two, then 8,
and so on. These numbers are simply not representable by a float.

For more information:
http://floating-point-gui.de/formats/fp/

--
  Simen


What is a concise way to test if floating point value is integral?

2013-08-28 Thread Paul Jurczak

I'm writing this rather ugly:

sqrt(cast(float)D) != round(sqrt(cast(float)D)

line and I'm looking for more concise notation without 
introducing a meaningless variable to hold expression being 
tested. Is there an equivalent of std.math.trunc(), which would 
return fractional portion instead, maybe frac()?