@@ -741,7 +741,7 @@ pub struct PlatformProperties {
741
741
pub canonical_nan_mantissa_msb : bool ,
742
742
pub canonical_nan_mantissa_second_to_msb : bool ,
743
743
pub canonical_nan_mantissa_rest : bool ,
744
- pub add_sub_mul_div_nan_propagation_mode : BinaryNaNPropagationMode ,
744
+ pub std_bin_ops_nan_propagation_mode : BinaryNaNPropagationMode ,
745
745
pub fma_nan_propagation_mode : TernaryNaNPropagationMode ,
746
746
pub fma_inf_zero_qnan_result : FMAInfZeroQNaNResult ,
747
747
pub round_to_integral_nan_propagation_mode : UnaryNaNPropagationMode ,
@@ -795,7 +795,7 @@ macro_rules! platform_properties_constants {
795
795
canonical_nan_mantissa_msb,
796
796
canonical_nan_mantissa_second_to_msb,
797
797
canonical_nan_mantissa_rest,
798
- add_sub_mul_div_nan_propagation_mode ,
798
+ std_bin_ops_nan_propagation_mode ,
799
799
fma_nan_propagation_mode,
800
800
fma_inf_zero_qnan_result,
801
801
round_to_integral_nan_propagation_mode,
@@ -815,7 +815,7 @@ platform_properties_constants! {
815
815
canonical_nan_mantissa_second_to_msb: false ,
816
816
canonical_nan_mantissa_rest: false ,
817
817
// FIXME: NaN propagation not known to be correct
818
- add_sub_mul_div_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
818
+ std_bin_ops_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
819
819
fma_nan_propagation_mode: TernaryNaNPropagationMode :: ThirdFirstSecondPreferringSNaN ,
820
820
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: CanonicalAndGenerateInvalid ,
821
821
round_to_integral_nan_propagation_mode: UnaryNaNPropagationMode :: First ,
@@ -826,7 +826,7 @@ platform_properties_constants! {
826
826
canonical_nan_mantissa_msb: true ,
827
827
canonical_nan_mantissa_second_to_msb: false ,
828
828
canonical_nan_mantissa_rest: false ,
829
- add_sub_mul_div_nan_propagation_mode : BinaryNaNPropagationMode :: AlwaysCanonical ,
829
+ std_bin_ops_nan_propagation_mode : BinaryNaNPropagationMode :: AlwaysCanonical ,
830
830
fma_nan_propagation_mode: TernaryNaNPropagationMode :: AlwaysCanonical ,
831
831
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: CanonicalAndGenerateInvalid ,
832
832
round_to_integral_nan_propagation_mode: UnaryNaNPropagationMode :: AlwaysCanonical ,
@@ -838,7 +838,7 @@ platform_properties_constants! {
838
838
canonical_nan_mantissa_second_to_msb: false ,
839
839
canonical_nan_mantissa_rest: false ,
840
840
// FIXME: NaN propagation not known to be correct
841
- add_sub_mul_div_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecond ,
841
+ std_bin_ops_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecond ,
842
842
fma_nan_propagation_mode: TernaryNaNPropagationMode :: FirstThirdSecond ,
843
843
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: PropagateAndGenerateInvalid ,
844
844
round_to_integral_nan_propagation_mode: UnaryNaNPropagationMode :: First ,
@@ -850,7 +850,7 @@ platform_properties_constants! {
850
850
canonical_nan_mantissa_second_to_msb: false ,
851
851
canonical_nan_mantissa_rest: false ,
852
852
// FIXME: NaN propagation not known to be correct
853
- add_sub_mul_div_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
853
+ std_bin_ops_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
854
854
fma_nan_propagation_mode: TernaryNaNPropagationMode :: ThirdFirstSecondPreferringSNaN ,
855
855
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: PropagateAndGenerateInvalid ,
856
856
round_to_integral_nan_propagation_mode: UnaryNaNPropagationMode :: First ,
@@ -863,7 +863,7 @@ platform_properties_constants! {
863
863
canonical_nan_mantissa_second_to_msb: false ,
864
864
canonical_nan_mantissa_rest: false ,
865
865
// FIXME: NaN propagation not known to be correct
866
- add_sub_mul_div_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecond ,
866
+ std_bin_ops_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecond ,
867
867
fma_nan_propagation_mode: TernaryNaNPropagationMode :: FirstSecondThird ,
868
868
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: FollowNaNPropagationMode ,
869
869
round_to_integral_nan_propagation_mode: UnaryNaNPropagationMode :: First ,
@@ -875,7 +875,7 @@ platform_properties_constants! {
875
875
canonical_nan_mantissa_second_to_msb: true ,
876
876
canonical_nan_mantissa_rest: true ,
877
877
// FIXME: NaN propagation not known to be correct
878
- add_sub_mul_div_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
878
+ std_bin_ops_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
879
879
fma_nan_propagation_mode: TernaryNaNPropagationMode :: FirstSecondThirdPreferringSNaN ,
880
880
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: FollowNaNPropagationMode ,
881
881
round_to_integral_nan_propagation_mode: UnaryNaNPropagationMode :: First ,
@@ -887,7 +887,7 @@ platform_properties_constants! {
887
887
canonical_nan_mantissa_second_to_msb: true ,
888
888
canonical_nan_mantissa_rest: false ,
889
889
// FIXME: NaN propagation not known to be correct
890
- add_sub_mul_div_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
890
+ std_bin_ops_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
891
891
fma_nan_propagation_mode: TernaryNaNPropagationMode :: FirstSecondThirdPreferringSNaN ,
892
892
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: FollowNaNPropagationMode ,
893
893
round_to_integral_nan_propagation_mode: UnaryNaNPropagationMode :: First ,
@@ -899,7 +899,7 @@ platform_properties_constants! {
899
899
canonical_nan_mantissa_second_to_msb: true ,
900
900
canonical_nan_mantissa_rest: true ,
901
901
// FIXME: NaN propagation not known to be correct
902
- add_sub_mul_div_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
902
+ std_bin_ops_nan_propagation_mode : BinaryNaNPropagationMode :: FirstSecondPreferringSNaN ,
903
903
fma_nan_propagation_mode: TernaryNaNPropagationMode :: FirstSecondThirdPreferringSNaN ,
904
904
fma_inf_zero_qnan_result: FMAInfZeroQNaNResult :: CanonicalAndGenerateInvalid ,
905
905
round_to_integral_nan_propagation_mode: UnaryNaNPropagationMode :: First ,
@@ -2026,7 +2026,7 @@ impl<Bits: FloatBitsType, FT: FloatTraits<Bits = Bits>> Float<FT> {
2026
2026
}
2027
2027
match properties
2028
2028
. platform_properties
2029
- . add_sub_mul_div_nan_propagation_mode
2029
+ . std_bin_ops_nan_propagation_mode
2030
2030
. calculate_propagation_results ( self_class, rhs_class)
2031
2031
{
2032
2032
BinaryNaNPropagationResults :: First => self . to_quiet_nan ( ) ,
@@ -2120,7 +2120,7 @@ impl<Bits: FloatBitsType, FT: FloatTraits<Bits = Bits>> Float<FT> {
2120
2120
}
2121
2121
match properties
2122
2122
. platform_properties
2123
- . add_sub_mul_div_nan_propagation_mode
2123
+ . std_bin_ops_nan_propagation_mode
2124
2124
. calculate_propagation_results ( self_class, rhs_class)
2125
2125
{
2126
2126
BinaryNaNPropagationResults :: First => self . to_quiet_nan ( ) ,
@@ -2169,7 +2169,7 @@ impl<Bits: FloatBitsType, FT: FloatTraits<Bits = Bits>> Float<FT> {
2169
2169
}
2170
2170
match properties
2171
2171
. platform_properties
2172
- . add_sub_mul_div_nan_propagation_mode
2172
+ . std_bin_ops_nan_propagation_mode
2173
2173
. calculate_propagation_results ( self_class, rhs_class)
2174
2174
{
2175
2175
BinaryNaNPropagationResults :: First => self . to_quiet_nan ( ) ,
@@ -2201,6 +2201,78 @@ impl<Bits: FloatBitsType, FT: FloatTraits<Bits = Bits>> Float<FT> {
2201
2201
)
2202
2202
}
2203
2203
}
2204
+ pub fn ieee754_remainder (
2205
+ & self ,
2206
+ rhs : & Self ,
2207
+ rounding_mode : Option < RoundingMode > ,
2208
+ fp_state : Option < & mut FPState > ,
2209
+ ) -> Self {
2210
+ assert_eq ! ( self . traits, rhs. traits) ;
2211
+ let properties = self . properties ( ) ;
2212
+ let mut default_fp_state = FPState :: default ( ) ;
2213
+ let fp_state = fp_state. unwrap_or ( & mut default_fp_state) ;
2214
+ let rounding_mode = rounding_mode. unwrap_or ( fp_state. rounding_mode ) ;
2215
+ let self_class = self . class ( ) ;
2216
+ let rhs_class = rhs. class ( ) ;
2217
+ if self_class. is_nan ( ) || rhs_class. is_nan ( ) {
2218
+ if self_class. is_signaling_nan ( ) || rhs_class. is_signaling_nan ( ) {
2219
+ fp_state. status_flags |= StatusFlags :: INVALID_OPERATION ;
2220
+ }
2221
+ match properties
2222
+ . platform_properties
2223
+ . std_bin_ops_nan_propagation_mode
2224
+ . calculate_propagation_results ( self_class, rhs_class)
2225
+ {
2226
+ BinaryNaNPropagationResults :: First => self . to_quiet_nan ( ) ,
2227
+ BinaryNaNPropagationResults :: Second => rhs. to_quiet_nan ( ) ,
2228
+ BinaryNaNPropagationResults :: Canonical => {
2229
+ Self :: quiet_nan_with_traits ( self . traits . clone ( ) )
2230
+ }
2231
+ }
2232
+ } else if self_class. is_infinity ( ) || rhs_class. is_zero ( ) {
2233
+ fp_state. status_flags |= StatusFlags :: INVALID_OPERATION ;
2234
+ Self :: quiet_nan_with_traits ( self . traits . clone ( ) )
2235
+ } else if rhs_class. is_infinity ( ) {
2236
+ if self_class. is_zero ( ) {
2237
+ self . clone ( )
2238
+ } else {
2239
+ Self :: from_real_algebraic_number_with_traits (
2240
+ & self . to_real_algebraic_number ( ) . expect ( "known to be finite" ) ,
2241
+ Some ( rounding_mode) ,
2242
+ Some ( fp_state) ,
2243
+ self . traits . clone ( ) ,
2244
+ )
2245
+ }
2246
+ } else {
2247
+ let lhs_value = self . to_real_algebraic_number ( ) . expect ( "known to be finite" ) ;
2248
+ let rhs_value = rhs. to_real_algebraic_number ( ) . expect ( "known to be finite" ) ;
2249
+ let quotient = & lhs_value / & rhs_value;
2250
+ let floor_quotient = quotient. to_integer_floor ( ) ;
2251
+ let fract_quotient = quotient - RealAlgebraicNumber :: from ( floor_quotient. clone ( ) ) ;
2252
+ let selected_quotient = match fract_quotient. cmp ( & Ratio :: new ( 1 , 2 ) . into ( ) ) {
2253
+ Ordering :: Less => floor_quotient,
2254
+ Ordering :: Greater => floor_quotient + 1 ,
2255
+ Ordering :: Equal => {
2256
+ if floor_quotient. is_even ( ) {
2257
+ floor_quotient
2258
+ } else {
2259
+ floor_quotient + 1
2260
+ }
2261
+ }
2262
+ } ;
2263
+ let remainder = lhs_value - rhs_value * RealAlgebraicNumber :: from ( selected_quotient) ;
2264
+ if remainder. is_zero ( ) {
2265
+ Self :: signed_zero_with_traits ( self . sign ( ) , self . traits . clone ( ) )
2266
+ } else {
2267
+ Self :: from_real_algebraic_number_with_traits (
2268
+ & remainder,
2269
+ Some ( rounding_mode) ,
2270
+ Some ( fp_state) ,
2271
+ self . traits . clone ( ) ,
2272
+ )
2273
+ }
2274
+ }
2275
+ }
2204
2276
/// compute `(self * factor) + term`
2205
2277
pub fn fused_mul_add (
2206
2278
& self ,
@@ -2671,7 +2743,7 @@ mod tests {
2671
2743
canonical_nan_sign: Negative, canonical_nan_mantissa_msb: false, \
2672
2744
canonical_nan_mantissa_second_to_msb: true, \
2673
2745
canonical_nan_mantissa_rest: true, \
2674
- add_sub_mul_div_nan_propagation_mode : FirstSecondPreferringSNaN, \
2746
+ std_bin_ops_nan_propagation_mode : FirstSecondPreferringSNaN, \
2675
2747
fma_nan_propagation_mode: FirstSecondThirdPreferringSNaN, \
2676
2748
fma_inf_zero_qnan_result: CanonicalAndGenerateInvalid, \
2677
2749
round_to_integral_nan_propagation_mode: First, \
0 commit comments