Help me please with this problem

I’m trying to find the number of decimal places and everything works fine except for a few things.


1.with the number 1.57 (also with the numbers 1.577, 1.5777, 1.5777 …) watch shows ovf:

2.Watch shows 1000, but the value still does not equal 1000:
.
which means 1000: the number of zeros minus 1 = the number of decimal places.1000 = 3-1 = 2.

10000 = 4-1 = 3.

the code itself:

This should be solved by doing the math first.
Q1 - What do you mean by “the number of decimal places”? To the left of the decimal point is easy. It’s the floor of log10(num) + 1 Examples:
23.5 --> floor(1.37) is 1 +1 = 2. 10–> 1 + 1 = 2 999–>3 1000–> 3
1.57, 1.577. 1.5777 all yield 1 (digits to left of dp)

Q2 - For the right of the decimal point, can you specify fixed point (also called engineering format)? Examples - 3 digits to the right. You can optionally trim trailing zeros) 1 1/3 --> 1.333 2 2/3–> 2.667 1 1/2 --> 1.5

Left + right plus the decimal point 455.250 --> (2+1) for before decimal point,
plus 1 for the decimal point, + 2 for the 250 eliminating the trailing 1 zero yields 6 printable digits.

Is this what you are asking?
If not, please give a list of some examples.

1 Like

I want to display the number of digits to the right of the comma: 1.45 - 2; 1.7658498-7;
and everything works, but doesn’t work with the number 1.57. watch writes ovf. and for some reason, extra numbers are taken from me: 1000.000000045. although I just use cycle for, and just division. Where does this inaccuracy come from?
look at my code and find errors.

  1. Why have you started at least 3 discussions on this one problem?
  2. Why are you showing us mostly empty screens above with just the output and no indication of where that output is coming from (and hence what it is supposed to be)? Position the screen to show us your code as well as the output before doing screenshot.
  3. You start by showing examples with integer multiples of 10 saying you expect results >0, then you tell us you are counting digits to the right of the decimal???
  4. Your code would be a lot easier to read if you used names for your variables instead of random letters.
  5. As stated in another post, you are talking about decimal numbers. Computers store numbers in binary. You start dividing and converting between the two, and you are going to get rounding errors. You can input 15.00000000000000000001 and expect to see 20 digits to the right of the decimal. By the time the computer converts it to binary and does multiple multiply/divide operations, it is probably going to think the number is 15 or maybe one digit less at 15.0000000000000000009
  6. How do you count the decimal digits of a number like 1/3? If there are no rounding errors, it will have infinite digits to the right of the decimal.
  7. If you are trying to determine precision of a number input by user, you will probably be better off reading a string, counting characters to the right of the decimal, then converting to a number. Trying to count decimal digits in a floating-point number stored in binary is an exercise in futility; computers are not as exact as we sometimes make them out to be.

You’re right. I will not use this method. I just did the function of displaying numbers on a four-digit seven-segment indicator. And everything worked fine, you could display letters and numbers, and negative ones too, with the exception of the comma. I just now tried to think of a function for calculating this comma. I have one idea.

I believe you are using a 4 digit display with a decimal point possibly displayed the right of each digit. Also, you’re using a library called SevSeg (your code includes Sevseg.h).

You are trying to automatically set the second parameter in this call:

sevseg.setNumber() – This function prints the number to the display. For example, sevseg.setNumber(4) will print the number “4” to the display. You can also print numbers with decimal points. For example, to print the number “4.999”, you would use sevseg.setNumber(4999, 3) . The second parameter (the 3) defines where the decimal point is located. In this case it’s 3 digits from the right most digit. On a single digit display, setting the second parameter to “0” turns on the decimal point, while setting it to “1” turns it off.

If this is all correct, you just need to determine where and if you want the decimal point.

For numbers less than 10, you can display up to 3 digits to the right of the decimal point. otherwise
For numbers less than 100, you can display up to 2 digits to the right of the decimal point. otherwise
For numbers less than 1000, you can display up to 1 digit to the right of the decimal point. otherwise
You can display a number only as high as 9999 (0 digits to the right of the decimal point)

From your examples it appears you are not displaying only integers.
You wish to have as many digits to the right of the decimal point as possible.
So far, is this all correct?

I think you will have an easier and better display if you do not have variable precision within a range. Thus if your numbers are less than 100 but not less than 10, you always display them as xx.xx , for example 37.51 and 10.50. You would not display those numbers as 37.51 and 10.5

That’s not a bad thing to do since it keeps the precision of the numbers in each of the displayable ranges constant rather than jumping around, which people might find confusing. Think dollars and cents. 7.49, 7.50, 7.51 is better than 7.49, 7.5, 7.51

I took a shot in the dark as to what you are asking. Did I get it right?

If I did, then all your code has to do is first figure which range to use for a number, calculate the needed number of digits to the right of the decimal point, and then make a call with to setNumber with two integers as arguments. The first argument, say for a number “ab.cd” is calculated as the integer ab * 100 + cd. The second argument would be 2.

As long as I’m shooting in the dark, :slight_smile:
I think you may be in a country where the decimal point is displayed as a comma and possibly the separator between groups in numbers with many digits is an empty space or a period. Very confusing. See this article:
( http://www.languageediting.com/format-numbers-eu-vs-us/ )

Thanks for the help. I have already corrected the code a bit.
1.57 he somehow strangely converted to the number 1.56999999999. therefore it did not work. I put rounding wherever possible. And now everything works. True only up to two characters. (1.99 1.9).
I don’t use any libraries at all. I try to solve all problems with basic functions.
Just today, I suddenly thought of using a different method:
if number rounded to one decimal place = original number, variable = 1.
if the number rounded to two decimal places = original number, variable = 2.
if number rounded to three decimal places = original number, variable = 3.
By the way, the bottom part of the code, where I check if more than 9 is less than 100 and so on, does not work anymore. I’ll clean it up later. I wrote this code before the point problem.
I also write fractional numbers separated by commas, but it doesn’t matter to me. Through the point, I also get tired. Already got used to the point while programming.

help is needed. Apparently, the translation from string to float (https://xod.io/libs/akate/string-number) does not work well:


.
As you can see, the conversion itself is not working properly

What is the dot-… node you are using? The library you mentioned seems to work for me on both UNO and simulation:

image

in principle, the code of the dot… itself is not important.


It is important here that the converter itself is not working correctly. The code is the same, but the result is different. although it should have been the same. you’ve shown an example, and you can see what’s not working correctly. 1.58 is converted to 1.59

String-to-int & string-to-float are just calling the C++ libraries atoi() & atof().

Oh wow…definitely problems somewhere. String-to-int can be even worse.
Simulator:
image

UNO:
image

Even weirder…that is starting simulation/debug with the “158” string. If I change the string during the run, it gets interpreted correctly (even if I change it back to “158”). String-to-float also produces the correct result if I change the value after simulation/debug has started.

It could be a problem with XOD initialization…@nkrkv is this something you can shed some light on?

I decided (tried) to solve this problem myself. It also seems to me that the watch is not working correctly. Well, here’s my string to number:

struct State {
};
{{ GENERATED_CODE }}
void evaluate(Context ctx) {
auto state = getState(ctx);
auto xString = getValue<input_IN>(ctx);
int N = length(xString) + 1;
char cString[N];
int b;
int count;
int len;
Number roundout;
for(int i=0;i<N;i++)
cString[i]=0;
dump(xString,cString);
Number nout= atof(cString);
for (b = round(nout); b>0; b = (b / 10)){
count++;
}
if (round(nout) != nout){
len = N-2;
}
else{
len = N - 1;
}
len = ((round(len) - round(count))+1);
roundout = round(pow(10, floor(len)));
nout = (floor(nout*roundout)/roundout);
emitValue<output_OUT>(ctx, nout);

}
The meaning is the same, but I tried to round the output number.
Just above I showed a photo where the watch showed 3, not 2. And now it shows correctly.

found an error in calculating count ++
replace round to floor:
for (b = floor(nout); b>0; b = (b / 10)){
count++;
}
and also in nout(34 line) replace the floor to round:
nout = (round(nout*roundout)/roundout);