If command does not work correctly.

3 views (last 30 days)
Bahadir Guven
Bahadir Guven on 18 Feb 2024
Edited: Stephen23 on 24 Feb 2024
Hello, I am preparing a gui for some formulas.
I want to prefix the formula results like mili-micro.
For example
Let the result be 0.0025V(voltage)
I want to write 2.5mV or 2500uV in the result section
For this, I want to get an integer by multiplying the resulting number by 10.
I will act according to how many times the multiplication is made.
For example
Let the answer be 0.026V, the number obtained from 3 multiplications is 26.
Since it is the result of 3 multiplications, the prefix will be "mili"
To understand where the multiplication stops, I check whether the number is an integer after each multiplication.
I did some research for this.
floor(V)==V
I will check the number this way.
There are some problems in the code
for loop doesn't stop where it should
I=input("enter number");
disp(I)
if I<1
for multiplication = 1:100
I=I*10
if floor(I)==I
break;
end
end
end
For example, I will enter two numbers
enter number 0.159
159.000000000000e-003
I =
1.59000000000000e+000
I =
15.9000000000000e+000
I =
159.000000000000e+000
>>
It worked correctly for that number and stopped when the if condition was true,when it was an integer.
enter number 0.234
234.000000000000e-003
I =
2.34000000000000e+000
I =
23.4000000000000e+000
I =
234.000000000000e+000
I =
2.34000000000000e+003
I =
23.4000000000000e+003
I =
234.000000000000e+003
I =
2.34000000000000e+006
I =
23.4000000000000e+006
I =
234.000000000000e+006
I =
2.34000000000000e+009
I =
23.4000000000000e+009
I =
234.000000000000e+009
I =
2.34000000000000e+012
I =
23.4000000000000e+012
I =
234.000000000000e+012
I =
2.34000000000000e+015
I =
23.4000000000000e+015
but in this example, even though it was an integer (even though the if condition was met), the for loop did not stop.
Can you help me I'm very confused
  1 Comment
Stephen23
Stephen23 on 24 Feb 2024
Edited: Stephen23 on 24 Feb 2024
"I want to prefix the formula results like mili-micro"
The simple approach is to download my FEX submission NUM2SIP():
and use it like this, with the examples from your question:
[num2sip(0.0025),'V']
ans = '2.5 mV'
[num2sip(0.026),'V']
ans = '26 mV'
and with the examples from your comment here:
[num2sip(32000000),'Hz']
ans = '32 MHz'
[num2sip(25000),'Ω']
ans = '25 kΩ'
[num2sip(0.0000035),'F']
ans = '3.5 µF'
Note that the space is required by the SI standard.
Most users underestimate the level of detail required to perform provide this conversion in a robust way**. Given that I have already created this function and tested it on hundeds of test-cases (included on FEX), why reinvent the wheel?
** I have systematically tested all FEX submissions (that I could find) that claim to make this conversion. Most of them are buggy (usually with very similar oversight e.g. regarding how to handle significant figures correctly and how to round up to the next prefix when required), very few of them actually gave the correct output.

Sign in to comment.

Answers (1)

Dyuman Joshi
Dyuman Joshi on 18 Feb 2024
Edited: Dyuman Joshi on 19 Feb 2024
Welcome to the world of floating point numbers, where not all numbers can be represented exactly in binary form.
0.234 is not exactly stored as 0.234 -
I=0.234; %input("enter number");
disp(I)
0.2340
%stored value upto 42 digits after decimal
fprintf('%0.42f', I)
0.234000000000000013544720900426909793168306
Let's check the value of I (upto 20 digits after decimal), with for a few iterations -
if I<1
for multiplication = 1:5%100
I=I*10;
fprintf('Iteration %d\nI = %0.20f\nfloor(I) = %0.20f\n\n', multiplication, I, floor(I))
if floor(I)==I
break;
end
end
end
Iteration 1 I = 2.34000000000000030198 floor(I) = 2.00000000000000000000 Iteration 2 I = 23.40000000000000213163 floor(I) = 23.00000000000000000000 Iteration 3 I = 234.00000000000002842171 floor(I) = 234.00000000000000000000 Iteration 4 I = 2340.00000000000045474735 floor(I) = 2340.00000000000000000000 Iteration 5 I = 23400.00000000000363797881 floor(I) = 23400.00000000000000000000
As you can see, I is not equal to floor(I), that's why the loop does not break.
When comparing floating point numbers, the best practice is to use a tolerance -
I = 0.234;
tol = 1e-3;
if I<1
for multiplication = 1:5%100
I=I*10;
fprintf('Iteration %d\nI = %0.20f\nfloor(I) = %0.20f\n\n', multiplication, I, floor(I))
if abs(floor(I)-I)<tol
break;
end
end
end
Iteration 1 I = 2.34000000000000030198 floor(I) = 2.00000000000000000000 Iteration 2 I = 23.40000000000000213163 floor(I) = 23.00000000000000000000 Iteration 3 I = 234.00000000000002842171 floor(I) = 234.00000000000000000000
Now you can observe that the loop has been terminated after 3 iterations, as initially expected.
Note - The choice of tolerance depends on requirement and other factors.
P.S - If you want to see the exact conversion of a number (to string format) based on IEEE floating point number system, you can utilize this FEX submission by James Tursa - https://in.mathworks.com/matlabcentral/fileexchange/22239-num2strexact-exact-version-of-num2str?s_tid=prof_contriblnk
  10 Comments
Stephen23
Stephen23 on 24 Feb 2024
"it can be any value between 10e-15 - 10e+15"
My function NUM2SIP() already copes with all real values from +REALMAX to -REALMAX, includes the SI prefixes added in 2022, and is tested on hundreds of testcases. Why reinvent the wheel?
Dyuman Joshi
Dyuman Joshi on 24 Feb 2024
Let me clarify - the input will be of the form of - 32MHz, 25k, and 3.5µF, and you want the output to be of the form - '32.000,000 hertz, 25.000 ohms and 0.0000035 farads' (diregarding the units, of course)?
Or is it the opposite of what I mentioned above?

Sign in to comment.

Categories

Find more on Characters and Strings in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!