decimal

Pages: 12
Hi all, in one part of the progtam I need to stop user from entering a number with more then 1 decimal place. So 1.1 is ok but 1.15 is not. I have no clue how to do it (whot kind of condition wil i put in?
Thank you in advance

1
2
3
4
5
6
7
8
 for (unsigned short a = 1; a <= numJudges; a++){
          do {
                    cout << "\n\n\tEnter score from judge number " << a << " : ";
                    cin >> score;
                    if (score < 0 || score > 6)
                        cout << "\n\n\tERROR! Score must be between 0 and 6." << endl;
                }
                while (score < 0 || score > 6);
you could read it in as a string (or convert it to a string just for validation) and find the first '.' and count the rest of the characters after this?
http://www.cplusplus.com/reference/string/string/find_first_of/


Last edited on
1
2
3
4
5
6
7
8
9
10
11
#include <cmath>

//...

double fractpart, intpart;

fractpart = modf(10.0 * val, &intpart);
if ((fractpart != 0.0) || (intpart < 0.0) || (intpart > 60.0))
{
    cout << "Illegal score value" << endl;
}


or

1
2
3
4
5
6
7
8
9
10
#include <cmath>

//...

double intpart;

if ((modf(10.0 * val, &intpart) != 0.0) || (intpart < 0.0) || (intpart > 60.0))
{
    cout << "Illegal score value" << endl;
}



EDIT: Fixed minimum value from 10.0 to 0.0.
Last edited on
I actually just thought of:


1
2
if (((score * 100))% 10 > 0)
cout << "ERROR";


but it will not compile

for the reason: invalid operands of type 'float' and 'int' to binary 'operator%'

Any thoughts?
Last edited on
Cast left argument of modulus operator to int:

1
2
if ((((int) (score * 100.0)) % 10) > 0)
    cout << "ERROR";


But it doesn't fit your intention because it only checks the second digit right of the dot.
It actually works with many decimal number.
I couldn't use your previous ideas 'cos I am true beginner, we only use #include <iostream> in class. I'm suppose to be able make this program with the little I know...
Thanks so much for your help.
You may use mutexes solution?!
I would just use strings and get line then parse for the mantissa and characteristic.
I think it's better to do the tiny amount of math in your program rather than incuring the extra expense of converting the entire number to a string.
1
2
3
if (trunc(x*10) != x*10) {
   cout << "one decimal only please.\n";
}
tcs I don't know what that is? So probably I shouldn't..

I thought abut converting to string and back giblit but it just looks like loads of mess, but thank you for a suggestion.

dhayden
What is trunk? And what will I set x to?
as mutexe said above:

you could read it in as a string (or convert it to a string just forvalidation) and find the
first '.' and count the rest of the characters after this?
http://www.cplusplus.com/reference/string/string/find_first_of/
I think it's better to do the tiny amount of math in your program rather than incuring the extra expense of converting the entire number to a string.
1
2
3
if (trunc(x*10) != x*10) {
   cout << "one decimal only please.\n";
}

Sure do it that way if you don't care about precision or accuracy. Some numbers like 4 or 5 could be represented as like 3.999999999 or 4.99999999 or even 4.000001 or 5.0000001 so those would show up as invalid when in fact if you read it as a string they would be valid.
I would love to use your idea giblit but I don't know what is trunc and x, should i #include anything for it? what will I declare tham as?

on the other note, if I have my numbers as string to calculate how many characters is there after '.' how will I turn it to a numeric value?
http://www.cplusplus.com/reference/cmath/trunc/
http://www.cplusplus.com/reference/string/

You may really find a lot of interesting information and example code on Cplusplus.com Reference manual and its Tutorial.
thanks tcs, I'm on it, fingers crossed;)
I got the idea, it makes perfect sense but it just doesn't work. If I put in number with one decimal it still say its incorrect, any idea why?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <cmath>
using namespace std;
int main (){
float score;
do {
        cout << "\n\n\tEnter score: ";
        cin >> score;

        cout << "\n\ttrunc(score*10) = " << trunc(score*10)
             << "\n\tscore * 10 = " << score *10 << endl;
if (trunc(score*10) != score*10) {
   cout << "\n\tone decimal only please.\n";
}
}
while (trunc(score*10) != score*10);

return 0;
}
1
2
3
if (trunc(x*10) != x*10) {
   cout << "one decimal only please.\n";
}

x is the number you want to check. trunc() truncates its argument to the integer towards zero: http://www.cplusplus.com/reference/cmath/trunc/

Sure do it that way if you don't care about precision or accuracy. Some numbers like 4 or 5 could be represented as like 3.999999999 or 4.99999999 or even 4.000001 or 5.0000001 so those would show up as invalid when in fact if you read it as a string they would be valid.

4 or 5 would represented exactly but your point is valid if there's a non-zero value after the decimal: when dealing with floating point numbers you normally need to consider rounding errors.
4 or 5 would represented exactly
If they are integers they are represented exactly. If they are floating point (float or double) then that is not guaranteed. This is the same reason that
1
2
3
4
int a = 5;
double b = 5.0;

std::cout << (a == b ? "Equal" : "Not Equal") << std::endl;
will result in Not Equal (more than likely it may depend on compiler) and why you can't compare floating points with the == operator effectively.
Last edited on
there is only one variable and it is a float, so it should compare float to float.

my other brilliant idea

1
2
if ((((int) (score * 100.0)) % 10) > 0)
    cout << "ERROR";


on the other hand is working most of the times, as in it will always show error when there is more than one decimal place, but it also shows error with 4.6 and few other numbers that shouldn't be errors
1
2
3
4
5
6
7
static double epsilon(0.000001);
static double allowedShift(10.0);

if (abs(trunc(x * allowedShift) - x * allowedShift) > epsilon)
{
   cout << "one decimal only please.\n";
}


Tests at least 5 digits of the fractional part.
Pages: 12