Reputation: 363
for a course at my university i need to write a program which converts a number into natural language e.g. if the user enters "2.55" the program outputs "two point five five". And i'm close to finish it the only thing i cant get are numbers after the point. I'm not allowed to use strings. Here is how i tried to get the count of decimal places:
i=0;
while((wert - (long int)wert) != 0){
wert /= 10;
i++;
}
But it gives me the value of 356 decimal places for the example number "2.55". Is there any method wihout using strings to count the decimal places?
Best Regards
Upvotes: 0
Views: 3862
Reputation: 7
char* fractpart(double f)
{
char chrstr[5];
char charary={'1','2','3',....,'0'};
int intary={1,2,3,...,0};
int count=0,x,y;
f=f-(int)f;
while(f<=1)
{
f=f*10;
for(y=0;y<10;y++)
{
if((int)f==intary[y])
{
chrstr[count]=charary[y];
break;
}
}
f=f-(int)f;
if(f<=0.01 || count==4)
break;
if(f<0)
f=-f;
count++;
}
return(chrstr);
}
Upvotes: 1
Reputation: 26185
The IEEE 64-bit binary number closest to 2.55 is 2.54999999999999982236431605997495353221893310546875, which only has 50 digits after the decimal point.
The repeated division makes no sense. Ignoring rounding error, the values of wert
would be 2.55, 0.255, 0.0255, 0.00255, etc. none of which is equal to any long. The loop terminates when wert
underflows to zero.
Instead, you should be multiplying by 10. However, if you keep the leading digits you may get a number too large to store as a long before getting equality. Instead, I suggest subtracting off the integer part at each step, and stopping when the result is zero.
That will still lead to a 50 decimal place answer, but if your professor insists on double, maybe that is what is wanted.
Upvotes: 1
Reputation: 311050
If the user is entering the number, it will be coming in as a string, or shall we say into a byte array, so there is no need to bring floating-point into it at all. Just locate the decimal place in the data and then start counting digits.
NB The question in your title is meaningless. Floating-point variables don't have decimal places, they have binary places, and decimal and binary places are incommensurable. If your professor wants you to use floating-point he needs re-education himself.
Upvotes: 2
Reputation: 14169
You have to know the maximal number of digits you have to support after the point.Let's say n
digits maximum. Multiply the fractional part of your number by 10^n
and then shift the resulting number right until the last digit is different from 0
to remove trailing zeroes. Then print the digits one by one:
void printDigitsAfterPoint(double x) {
int k = Math.round((x-(int) x)*Math.pow10(n));
// remove trailing zeroes
while (k!=0 && k%10==0) {
k/=10;
}
// output digits
while (k!=0) {
output(k%10); // you already should have a method like this...
k/=10;
}
}
Make sure to add code for handling negative values of x
. I'm sure your prof will try that...
EDIT: Forgot to change the declaration. Fixed.
Upvotes: 0
Reputation: 234875
You will not be able to use a double
to do this due to floating point precision. For example, a double
set to 0.2 will have many more decimal places than 1 since 0.2 cannot be represented precisely. (Why not examine the actual value of the double
in your debugger?) 2.55 cannot be represented precisely either.
Probably the simplest thing for you to do here is use a string to represent your number and base your parser on that.
Upvotes: 2