LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Numeric comparison fails if multiply by 1000

Hello,

the picture below should explain better than many words.

 

Immagine 2026-08-07 124114.pngImmagine 2026-08-07 124114.png

 

If I set "Numeric IN 2" to 1,5E-4 and multiply by 100 I get "Compare 2" = true.

So when multiplying by 1000 some limit is exceeded some how; any idea what that limit is?

Or a workaround to make it work anyway.

 

Thanks

 

0 Kudos
Message 1 of 11
(1,492 Views)

If you increase the precision shown you'll see that 0,015 isn't represented exactly. That's a known limitation of floats. For comparison, multiply by the factor (e.g. 10E6 for 6 digits) and compare the integers.

Yamaeda_0-1786101244477.pngYamaeda_0-1786101244477.png

Since the decimal part is binary (i like to call them binals), which bits would need to be active to get 0.015?

 

The binary version of 0,015 = 

Yamaeda_1-1786101474774.pngYamaeda_1-1786101474774.png

 

From wikipedia

Yamaeda_2-1786101755042.pngYamaeda_2-1786101755042.png

So the fraction starts with "1110101110000101"

 

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
Message 2 of 11
(1,474 Views)

Equality checks for floating points is a lost cause. This is not just a LabVIEW problem: all programming languages that use this IEEE-754 will have this issue. You should compare if the value is in a range.



There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 3 of 11
(1,458 Views)

@crossrulz wrote:

Equality checks for floating points is a lost cause. This is not just a LabVIEW problem: all programming languages that use this IEEE-754 will have this issue. You should compare if the value is in a range.


This is absolutely perfectly true. However, some programming languages provide additional functions or macros such as relative_eq!(), as well as static analysis warnings for such comparisons.

 

For example:

 

#![warn(clippy::float_cmp)]
use approx::relative_eq;

fn main() {
	println!("\nCompare 1.5E-2 and 1.5E-5 * 1000:\n");

    println!("Strict comparison of Floats (f32):");
	let a = 1.5E-2_f32;
	let b = 1.5E-5_f32 * 1000.0;
	println!("{a} == {b} > {}\n", a == b);

	println!("Strict comparison of Doubles (f64):");
	let a = 1.5E-2_f64;
	let b = 1.5E-5_f64 * 1000.0;
	println!("{a} == {b} > {}\n", a == b);

	println!("Doubles (f64) with tolreance:");
	let a = 1.5E-2_f64;
	let b = 1.5E-5_f64 * 1000.0;
	println!("{a} == {b} > {}\n", 
		(a - b).abs() <= f64::EPSILON * a.abs().max(b.abs()));

	println!("Doubles (f64) with relative_eq!():");
	let a = 1.5E-2_f64;
	let b = 1.5E-5_f64 * 1000.0;
	println!("{a} == {b} > {}", relative_eq!(a, b));
}

 

The beauty of relative_eq!() is that it encapsulates the tricky tolerance logic, so you don't have to choose and maintain arbitrary epsilon values yourself. Comparing directly against naked f64::EPSILON is generally not reliable across the full range of floating-point values because the appropriate tolerance depends on the magnitude of the numbers being compared, this needs to be corrected accordingly.

 

Result:

 

>cargo run

Compare 1.5E-2 and 1.5E-5 * 1000:

Strict comparison of Floats (f32):
0.015 == 0.015 > true

Strict comparison of Doubles (f64):
0.015 == 0.015000000000000001 > false

Doubles (f64) with tolreance:
0.015 == 0.015000000000000001 > true

Doubles (f64) with relative_eq!():
0.015 == 0.015000000000000001 > true

 

By the way, the strict comparison for floats works for these particular f32 values. In LabVIEW, it also evaluates to true:

 

lv-snip.pnglv-snip.png

 

Back to warnings, the linter output looks like this:

 

>cargo clippy

warning: strict comparison of `f32` or `f64`
  --> src\main.rs:10:32
   |
10 |     println!("{a} == {b} > {}\n", a == b);
   |                                   ^^^^^^ 
   | help: consider comparing them within some margin 
   | of error: `(a - b).abs() < error_margin`
   |
   = help: for further information visit
   https://rust-lang.github.io/rust-clippy/rust-1.97.0/index.html#float_cmp
note: the lint level is defined here
  --> src\main.rs:1:9
   |
 1 | #![warn(clippy::float_cmp)]
   |         ^^^^^^^^^^^^^^^^^

This is one of the reasons I like Rust. I'm not sure whether the LabVIEW VI Analyzer can detect this issue. With the default configuration and all built-in tests enabled, the analysis completed without any warnings or failures:

Screenshot 2026-08-07 14.56.34.pngScreenshot 2026-08-07 14.56.34.png

It is probably possible to implement a custom analyzer test for this with help of VI scripting, but I haven't tried doing so before.

Message 4 of 11
(1,429 Views)

One simple solution is this:

Yamaeda_0-1786111766445.pngYamaeda_0-1786111766445.png

 

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 5 of 11
(1,373 Views)

@Yamaeda wrote:

One simple solution is this:

Yamaeda_0-1786111766445.pngYamaeda_0-1786111766445.png

 


This will obviously fail for the cases like this:

 

Screenshot 2026-08-07 16.27.32.pngScreenshot 2026-08-07 16.27.32.png

I guess I saw a general approach somewhere on this forum, but I don’t remember where.
0 Kudos
Message 6 of 11
(1,363 Views)

The learning book says that a generic implementation should perform both relative and absolute comparisons, something like this:

 

snip2.pngsnip2.png

 

Refer to the relative_eq implementation and the article Comparing Floating Point Numbers.

Message 7 of 11
(1,345 Views)

Hey guys, I know that this community is full of skilled people, but I didn't expect so many tips and solutions in just few hours.
Thanks a lot to everyone for chiming in to help. I'll be back to the office in a couple of weeks, and along with a colleague we'll try to apply the solution that will best fit into our project.
Again, thank you very much, I will keep you updated in case of any new findings.

Message 8 of 11
(1,318 Views)

I can't remember where I found this but I believe that's what this does

snipCapture.PNGsnipCapture.PNG

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 9 of 11
(1,298 Views)

@Andrey_Dmitriev wrote:


This will obviously fail for the cases like this:

 

Screenshot 2026-08-07 16.27.32.pngScreenshot 2026-08-07 16.27.32.png

I guess I saw a general approach somewhere on this forum, but I don’t remember where.

Yes, ofc. If the change is much smaller than the tolerance that's expected. 🙂 I like your other Absolute+Relative check.

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 10 of 11
(1,166 Views)