File tree Expand file tree Collapse file tree 3 files changed +28
-0
lines changed
library/std/src/Std/OpenQASM
source/compiler/qsc_qasm/src/stdlib Expand file tree Collapse file tree 3 files changed +28
-0
lines changed Original file line number Diff line number Diff line change @@ -85,6 +85,13 @@ function DoubleAsAngle(value : Double, size : Int) : Angle {
85
85
value = value + tau ;
86
86
}
87
87
88
+ // Handle the edge case where modulo returns tau due to floating-point precision
89
+ // we've seen this when the user rotates by f64::EPSILON / 2.0 causing the value
90
+ // to be still equal to tau after the modulo operation.
91
+ if value >= tau {
92
+ value = 0 .;
93
+ }
94
+
88
95
Std .Diagnostics .Fact (value >= 0 ., "Value must be >= 0." );
89
96
Std .Diagnostics .Fact (value < tau , "Value must be < tau." );
90
97
Std .Diagnostics .Fact (size > 0 , "Size must be > 0" );
Original file line number Diff line number Diff line change @@ -52,6 +52,17 @@ impl Angle {
52
52
val += TAU ;
53
53
}
54
54
55
+ // Handle the edge case where modulo returns tau due to floating-point precision
56
+ // we've seen this when the user rotates by f64::EPSILON / 2.0 causing the value
57
+ // to be still equal to tau after the modulo operation.
58
+ if val >= TAU {
59
+ val = 0. ;
60
+ }
61
+
62
+ assert ! ( val >= 0. , "Value must be >= 0." ) ;
63
+ assert ! ( val < TAU , "Value must be < tau." ) ;
64
+ assert ! ( size > 0 , "Size must be > 0" ) ;
65
+
55
66
// If the size is > f64::MANTISSA_DIGITS, the cast to f64
56
67
// on the next lines will loose precission.
57
68
if size > f64:: MANTISSA_DIGITS {
Original file line number Diff line number Diff line change 5
5
#![ allow( clippy:: unreadable_literal) ]
6
6
7
7
use std:: convert:: TryInto ;
8
+ use std:: f64;
8
9
use std:: f64:: consts:: { PI , TAU } ;
9
10
10
11
use super :: Angle ;
@@ -269,3 +270,12 @@ fn test_angle_cast_truncation() {
269
270
assert_eq ! ( new_angle. value, 0b1010 ) ;
270
271
assert_eq ! ( new_angle. size, 4 ) ;
271
272
}
273
+
274
+ #[ test]
275
+ fn test_angle_off_by_less_than_epsilon_from_tau_maintains_invariants ( ) {
276
+ // testing (-f64::EPSILON / 2.0) % f64::EPSILON + f64::EPSILON equals f64::EPSILON
277
+ // we need to ensure that the angle is still in the range [0, TAU)
278
+ let angle = Angle :: from_f64_maybe_sized ( -f64:: EPSILON / 2.0 , None ) ;
279
+ assert_eq ! ( angle. value, 0 ) ;
280
+ assert ! ( angle. size == 53 ) ;
281
+ }
You can’t perform that action at this time.
0 commit comments