Gaijinco wrote On 09/26/05 16:07,:

> Sooner or later everytime I found recreational programming challenges I

> stumble with how I test if a number is has decimal places differnt than

> 0?

>

> For example if I want to know if a number is a square number (i.e. a

> number which square root is a positive number as 4, 9, 16 have) I do

> something like:

>

> int square = sqrt(number);

>

> if((int)square==square)

> // number is a perfect square
.... and the test is a tautology.

> else

> // number is not a perfect square

>

> Is there a function or a language-specific-way to do this?
The code you've shown will (if it doesn't invoke

undefined behavior) declare that every number is a

perfect square: 1, 2, 3.14, and even -42.

To test whether a floating-point number is an

integer with no fractional part, you could try

if ((int)fpn == fpn) ...

This runs into trouble when the magnitude of fpn

is large, so large that its value is outside the range

of numbers representable as `int'.

As an improvement you might try

if (fmod(fpn, 1.0) == 0.0) ...

This is still vulnerable to the "graininess" of

floating-point numbers, which are not mathematical real

numbers with infinite precision.

You cannot usually expect sqrt(fpn) to be the exact square

root of fpn. sqrt(fpn) will be very close to the exact root,

but will (in general) be just a little bit different from the

true value. There could be several different fpn values for

which sqrt(fpn) would deliver exactly the same slightly wrong

answer: both sqrt(4.0) and sqrt(4.0 + tiny_number) might

produce 2.0 as an answer. If you decide that a number is a

perfect square if its computed square root turns out to be an

integer, you will erroneously conclude that 4.0+tiny_number is

a perfect square.

A possibly more thorough test might compute the square

root, test whether it's an integer, and then test whether

its square equals the original number:

double root = sqrt(number);

if (fmod(root, 1.0) == 0.0 && root * root == number)

.... but even this may have some problems. I am always uneasy

when comparing floating-point quantities for exact equality,

mostly because fpn's are usually regarded as approximations

to begin with. You usually need an "approximately equal"

test of some kind, and such a test isn't well suited to the

purely yet/no nature of perfect squaredom.

For "number-theoretic" calculations you'll usually be much

better off using integers of some flavor. If the numbers grow

large you may need to resort to a "bignum" package; several

are available.

--

http://www.velocityreviews.com/forums/(E-Mail Removed)