Skip to content

Commit 28f34f9

Browse files
committed
Add additional checks to remove possibility of NotNaN containing NaN
Fixes #17
1 parent 7fcc0b6 commit 28f34f9

File tree

1 file changed

+43
-24
lines changed

1 file changed

+43
-24
lines changed

src/lib.rs

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ impl Into<f64> for NotNaN<f64> {
211211

212212
/// Creates a NotNaN value from a Float.
213213
///
214-
/// Panics if the provided value is NaN.
214+
/// Panics if the provided value is NaN or the computation results in NaN
215215
impl<T: Float> From<T> for NotNaN<T> {
216216
fn from(v: T) -> Self {
217217
assert!(!v.is_nan());
@@ -239,35 +239,38 @@ impl<T: Float> Add for NotNaN<T> {
239239

240240
/// Adds a float directly.
241241
///
242-
/// Panics if the provided value is NaN.
242+
/// Panics if the provided value is NaN or the computation results in NaN
243243
impl<T: Float> Add<T> for NotNaN<T> {
244244
type Output = Self;
245245

246246
fn add(self, other: T) -> Self {
247247
assert!(!other.is_nan());
248-
NotNaN(self.0 + other)
248+
NotNaN::new(self.0 + other).expect("Addition resulted in NaN")
249249
}
250250
}
251251

252252
impl AddAssign for NotNaN<f64> {
253253
fn add_assign(&mut self, other: Self) {
254254
self.0 += other.0;
255+
assert!(!self.0.is_nan(), "Addition resulted in NaN")
255256
}
256257
}
257258

258259
impl AddAssign for NotNaN<f32> {
259260
fn add_assign(&mut self, other: Self) {
260261
self.0 += other.0;
262+
assert!(!self.0.is_nan(), "Addition resulted in NaN")
261263
}
262264
}
263265

264266
/// Adds a float directly.
265267
///
266-
/// Panics if the provided value is NaN.
268+
/// Panics if the provided value is NaN or the computation results in NaN
267269
impl AddAssign<f64> for NotNaN<f64> {
268270
fn add_assign(&mut self, other: f64) {
269271
assert!(!other.is_nan());
270272
self.0 += other;
273+
assert!(!self.0.is_nan(), "Addition resulted in NaN")
271274
}
272275
}
273276

@@ -278,90 +281,97 @@ impl AddAssign<f32> for NotNaN<f32> {
278281
fn add_assign(&mut self, other: f32) {
279282
assert!(!other.is_nan());
280283
self.0 += other;
284+
assert!(!self.0.is_nan(), "Addition resulted in NaN")
281285
}
282286
}
283287

284288
impl<T: Float> Sub for NotNaN<T> {
285289
type Output = Self;
286290

287291
fn sub(self, other: Self) -> Self {
288-
NotNaN(self.0 - other.0)
292+
NotNaN::new(self.0 - other.0).expect("Subtraction resulted in NaN")
289293
}
290294
}
291295

292296
/// Subtracts a float directly.
293297
///
294-
/// Panics if the provided value is NaN.
298+
/// Panics if the provided value is NaN or the computation results in NaN
295299
impl<T: Float> Sub<T> for NotNaN<T> {
296300
type Output = Self;
297301

298302
fn sub(self, other: T) -> Self {
299303
assert!(!other.is_nan());
300-
NotNaN(self.0 - other)
304+
NotNaN::new(self.0 - other).expect("Subtraction resulted in NaN")
301305
}
302306
}
303307

304308
impl SubAssign for NotNaN<f64> {
305309
fn sub_assign(&mut self, other: Self) {
306310
self.0 -= other.0;
311+
assert!(!self.0.is_nan(), "Subtraction resulted in NaN")
307312
}
308313
}
309314

310315
impl SubAssign for NotNaN<f32> {
311316
fn sub_assign(&mut self, other: Self) {
312317
self.0 -= other.0;
318+
assert!(!self.0.is_nan(), "Subtraction resulted in NaN")
313319
}
314320
}
315321

316322
/// Subtracts a float directly.
317323
///
318-
/// Panics if the provided value is NaN.
324+
/// Panics if the provided value is NaN or the computation results in NaN
319325
impl SubAssign<f64> for NotNaN<f64> {
320326
fn sub_assign(&mut self, other: f64) {
321327
assert!(!other.is_nan());
322328
self.0 -= other;
329+
assert!(!self.0.is_nan(), "Subtraction resulted in NaN")
323330
}
324331
}
325332

326333
/// Subtracts a float directly.
327334
///
328-
/// Panics if the provided value is NaN.
335+
/// Panics if the provided value is NaN or the computation results in NaN
329336
impl SubAssign<f32> for NotNaN<f32> {
330337
fn sub_assign(&mut self, other: f32) {
331338
assert!(!other.is_nan());
332339
self.0 -= other;
340+
assert!(!self.0.is_nan(), "Subtraction resulted in NaN")
333341
}
334342
}
335343

336344
impl<T: Float> Mul for NotNaN<T> {
337345
type Output = Self;
338346

339347
fn mul(self, other: Self) -> Self {
340-
NotNaN(self.0 * other.0)
348+
NotNaN::new(self.0 * other.0).expect("Multiplication resulted in NaN")
341349
}
342350
}
343351

344352
/// Multiplies a float directly.
345353
///
346-
/// Panics if the provided value is NaN.
354+
/// Panics if the provided value is NaN or the computation results in NaN
347355
impl<T: Float> Mul<T> for NotNaN<T> {
348356
type Output = Self;
349357

350358
fn mul(self, other: T) -> Self {
351359
assert!(!other.is_nan());
352-
NotNaN(self.0 * other)
360+
NotNaN::new(self.0 * other).expect("Multiplication resulted in NaN")
353361
}
354362
}
355363

356364
impl MulAssign for NotNaN<f64> {
357365
fn mul_assign(&mut self, other: Self) {
358366
self.0 *= other.0;
367+
assert!(!self.0.is_nan(), "Multiplication resulted in NaN")
359368
}
360369
}
361370

362371
impl MulAssign for NotNaN<f32> {
363372
fn mul_assign(&mut self, other: Self) {
364373
self.0 *= other.0;
374+
assert!(!self.0.is_nan(), "Multiplication resulted in NaN")
365375
}
366376
}
367377

@@ -377,123 +387,132 @@ impl MulAssign<f64> for NotNaN<f64> {
377387

378388
/// Multiplies a float directly.
379389
///
380-
/// Panics if the provided value is NaN.
390+
/// Panics if the provided value is NaN or the computation results in NaN
381391
impl MulAssign<f32> for NotNaN<f32> {
382392
fn mul_assign(&mut self, other: f32) {
383393
assert!(!other.is_nan());
384394
self.0 *= other;
395+
assert!(!self.0.is_nan(), "Multiplication resulted in NaN")
385396
}
386397
}
387398

388399
impl<T: Float> Div for NotNaN<T> {
389400
type Output = Self;
390401

391402
fn div(self, other: Self) -> Self {
392-
NotNaN(self.0 / other.0)
403+
NotNaN::new(self.0 / other.0).expect("Division resulted in NaN")
393404
}
394405
}
395406

396407
/// Divides a float directly.
397408
///
398-
/// Panics if the provided value is NaN.
409+
/// Panics if the provided value is NaN or the computation results in NaN
399410
impl<T: Float> Div<T> for NotNaN<T> {
400411
type Output = Self;
401412

402413
fn div(self, other: T) -> Self {
403414
assert!(!other.is_nan());
404-
NotNaN(self.0 / other)
415+
NotNaN::new(self.0 / other).expect("Division resulted in NaN")
405416
}
406417
}
407418

408419
impl DivAssign for NotNaN<f64> {
409420
fn div_assign(&mut self, other: Self) {
410421
self.0 /= other.0;
422+
assert!(!self.0.is_nan(), "Division resulted in NaN")
411423
}
412424
}
413425

414426
impl DivAssign for NotNaN<f32> {
415427
fn div_assign(&mut self, other: Self) {
416428
self.0 /= other.0;
429+
assert!(!self.0.is_nan(), "Division resulted in NaN")
417430
}
418431
}
419432

420433
/// Divides a float directly.
421434
///
422-
/// Panics if the provided value is NaN.
435+
/// Panics if the provided value is NaN or the computation results in NaN
423436
impl DivAssign<f64> for NotNaN<f64> {
424437
fn div_assign(&mut self, other: f64) {
425438
assert!(!other.is_nan());
426439
self.0 /= other;
440+
assert!(!self.0.is_nan(), "Division resulted in NaN")
427441
}
428442
}
429443

430444
/// Divides a float directly.
431445
///
432-
/// Panics if the provided value is NaN.
446+
/// Panics if the provided value is NaN or the computation results in NaN
433447
impl DivAssign<f32> for NotNaN<f32> {
434448
fn div_assign(&mut self, other: f32) {
435449
assert!(!other.is_nan());
436450
self.0 /= other;
451+
assert!(!self.0.is_nan(), "Division resulted in NaN")
437452
}
438453
}
439454

440455
impl<T: Float> Rem for NotNaN<T> {
441456
type Output = Self;
442457

443458
fn rem(self, other: Self) -> Self {
444-
NotNaN(self.0 % other.0)
459+
NotNaN::new(self.0 % other.0).expect("Rem resulted in NaN")
445460
}
446461
}
447462

448463
/// Calculates `%` with a float directly.
449464
///
450-
/// Panics if the provided value is NaN.
465+
/// Panics if the provided value is NaN or the computation results in NaN
451466
impl<T: Float> Rem<T> for NotNaN<T> {
452467
type Output = Self;
453468

454469
fn rem(self, other: T) -> Self {
455470
assert!(!other.is_nan());
456-
NotNaN(self.0 % other)
471+
NotNaN::new(self.0 % other).expect("Rem resulted in NaN")
457472
}
458473
}
459474

460475
impl RemAssign for NotNaN<f64> {
461476
fn rem_assign(&mut self, other: Self) {
462477
self.0 %= other.0;
478+
assert!(!self.0.is_nan(), "Rem resulted in NaN")
463479
}
464480
}
465481

466482
impl RemAssign for NotNaN<f32> {
467483
fn rem_assign(&mut self, other: Self) {
468484
self.0 %= other.0;
485+
assert!(!self.0.is_nan(), "Rem resulted in NaN")
469486
}
470487
}
471488

472489
/// Calculates `%=` with a float directly.
473490
///
474-
/// Panics if the provided value is NaN.
491+
/// Panics if the provided value is NaN or the computation results in NaN
475492
impl RemAssign<f64> for NotNaN<f64> {
476493
fn rem_assign(&mut self, other: f64) {
477494
assert!(!other.is_nan());
478495
self.0 %= other;
496+
assert!(!self.0.is_nan(), "Rem resulted in NaN")
479497
}
480498
}
481499

482500
/// Calculates `%=` with a float directly.
483501
///
484-
/// Panics if the provided value is NaN.
502+
/// Panics if the provided value is NaN or the computation results in NaN
485503
impl RemAssign<f32> for NotNaN<f32> {
486504
fn rem_assign(&mut self, other: f32) {
487505
assert!(!other.is_nan());
488506
self.0 %= other;
507+
assert!(!self.0.is_nan(), "Rem resulted in NaN")
489508
}
490509
}
491510

492511
impl<T: Float> Neg for NotNaN<T> {
493512
type Output = Self;
494513

495514
fn neg(self) -> Self {
496-
NotNaN(-self.0)
515+
NotNaN::new(-self.0).expect("Negation resulted in NaN")
497516
}
498517
}
499518

0 commit comments

Comments
 (0)