How to tell if a number has decimal places different than 0

H

Howard

Gaijinco said:
The issue at hand was that I would normally do this for testing if an
integrer was a square number:

bool square_number(int number){
if(sqrt(number)==floor(sqrt(number)))
return true;
else
return false;
}

However "sqrt(number)==floor(sqrt(number))" seemed an awkward way to
test it, so I wasn't sure if there was a "clenear" way to do it.

No sense computing the square root twice. You could store the result of
sqrt() in a float (or double) and compare that against the floor() of
itself.

There are also integer techniques for testing if a number is a perfect
square, but those may not be significantly faster in practice (if that's
even an issue).

-Howard
 
M

Mark McIntyre

He said, it is not continuous. The point is:

I know what he's saying but its not relevant IMHO.
a) every float represents a unique real number and does so exactly.

IME most people care about the exactitude coming from human readable
numbers, not the other way round.....
 
K

kar1107

Gaijinco said:
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?

If we know the internal representation of the double, we can use that
information. But I'm not sure if that detail is implementation
specific.
We can use snprintf routine to get a textual representation of the
double
and look to see if the decimal part is zero. Something like,

#include <stdio.h>
#include <stdlib.h>


/*
* 1 if d is has decimal part zero
* 0 if d has non zero decimal part
* -1 error
*/
int
is_double_integer (double d)
{
int buff_size;
char *buff, *p_dot, *p;


buff_size = snprintf(NULL, 0, "%.16f", d);
if (buff_size < 0) return -1;


buff = malloc(buff_size + 1);
if (!buff) return -1;


snprintf(buff, buff_size+1, "%.16f", d);


p_dot = strchr(buff, '.');


if (!p_dot) {
free(buff);
return -1;
}


for (p = p_dot+1; *p; ++p) {
if (*p != '0') {
free(buff);
return 0;
}
}
free(buff);
return 1;
}


int main (void)
{
double d = 23.2342443400000001;


printf("[%f] : is decimal part zero? [%d]\n", d,
is_double_integer(d));
d = 12323.00000000001;
printf("[%f] : is decimal part zero? [%d]\n", d,
is_double_integer(d));
d = 12323.00000000000000;
printf("[%f] : is decimal part zero? [%d]\n", d,
is_double_integer(d));
return 0;
}

$>./a.out
[23.234244] : is decimal part zero? [0]
[12323.000000] : is decimal part zero? [0]
[12323.000000] : is decimal part zero? [1]

Karthik
 
R

Richard Bos

No sense computing the square root twice. You could store the result of
sqrt() in a float (or double) and compare that against the floor() of
itself.

Any halfway decent compiler will perform that optimisation for you, and
possibly do so even more efficiently than using another variable would.

Richard
 
H

Howard

Richard Bos said:
Any halfway decent compiler will perform that optimisation for you, and
possibly do so even more efficiently than using another variable would.

Richard

Really? Do you know that for sure? That seems like an odd thing to expect
of a compiler... optimizing out an explicit function call. I can see how it
would be easy enough to implement, given that the compiler writers also
wrote the sqrt function and know what it does (provided it hasn't been
hidden by a user-defined function of the same name), but I'd still suggest
that it's poor coding practice to call a function twice when you only need
it called once. Writing poor code because you believe that the optimization
step will make it better than well-written code is, well, odd, in my
opinion.

-Howard
 
K

Karl Heinz Buchegger

Howard said:
Really? Do you know that for sure? That seems like an odd thing to expect
of a compiler... optimizing out an explicit function call.

:)

You should see what some compilers do with the str...() family of functions
 
A

Arthur J. O'Dwyer

Any halfway decent compiler will perform that optimisation for you, and
possibly do so even more efficiently than using another variable would.

But any halfway decent compiler would perform the same optimization if
you used another variable. And if you use another variable, your code will
probably work faster even on implementations that /aren't/ halfway decent.
Plus it's one fewer place to make a mistake like

if(sqrt(number)==floor(sqr(number)))
or
if(sqrt(number)==floor(sqrt(n)))

(admittedly both highly unlikely errors, but I've seen dumber mistakes).
So I'd split out the calculation as Howard recommended --- even if not
for exactly the same reason.

-Arthur
 
A

Anonymous 7843

Any halfway decent compiler will perform that optimisation for you, and
possibly do so even more efficiently than using another variable would.

However, one shouldn't get in the habit of relying on this.
Functions outside the standard (or implementation provided)
libraries cannot easily be identified to be pure, so in general,
2nd calls cannot be optimized out.
 
E

Eric Sosman

Anonymous 7843 wrote On 09/28/05 13:34,:
However, one shouldn't get in the habit of relying on this.
Functions outside the standard (or implementation provided)
libraries cannot easily be identified to be pure, so in general,
2nd calls cannot be optimized out.

Note that sqrt() is not pure, because it can have the
side-effect of setting errno. In C99, it can also raise
the "invalid" floating-point exception.
 
A

Anonymous 7843

Anonymous 7843 wrote On 09/28/05 13:34,:

Note that sqrt() is not pure, because it can have the
side-effect of setting errno. In C99, it can also raise
the "invalid" floating-point exception.

Good point!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top