Remove lossy casting in logspace
Currently `logspace` does a lossy cast from `F::Int` to `usize`. This could be problematic in the rare cases that this is called with a step count exceeding what is representable in `usize`. Resolve this by instead adding bounds so the float's integer type itself can be iterated.
This commit is contained in:
committed by
Trevor Gross
parent
e8c501861a
commit
cf58a7ce90
@@ -1,5 +1,7 @@
|
||||
//! A generator that produces logarithmically spaced values within domain bounds.
|
||||
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use libm::support::{IntTy, MinInt};
|
||||
|
||||
use crate::domain::HasDomain;
|
||||
@@ -34,6 +36,7 @@ pub fn get_test_cases<Op>(_ctx: &CheckCtx) -> impl Iterator<Item = (Op::FTy,)>
|
||||
where
|
||||
Op: MathOp + HasDomain<Op::FTy>,
|
||||
IntTy<Op::FTy>: TryFrom<usize>,
|
||||
RangeInclusive<IntTy<Op::FTy>>: Iterator,
|
||||
{
|
||||
let domain = Op::DOMAIN;
|
||||
let start = domain.range_start();
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
//! Helpful numeric operations.
|
||||
|
||||
use std::cmp::min;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use libm::support::{CastInto, Float};
|
||||
use libm::support::Float;
|
||||
|
||||
use crate::{Int, MinInt};
|
||||
|
||||
@@ -214,7 +215,10 @@ fn as_ulp_steps<F: Float>(x: F) -> Option<F::SignedInt> {
|
||||
/// to logarithmic spacing of their values.
|
||||
///
|
||||
/// Note that this tends to skip negative zero, so that needs to be checked explicitly.
|
||||
pub fn logspace<F: FloatExt>(start: F, end: F, steps: F::Int) -> impl Iterator<Item = F> {
|
||||
pub fn logspace<F: FloatExt>(start: F, end: F, steps: F::Int) -> impl Iterator<Item = F>
|
||||
where
|
||||
RangeInclusive<F::Int>: Iterator,
|
||||
{
|
||||
assert!(!start.is_nan());
|
||||
assert!(!end.is_nan());
|
||||
assert!(end >= start);
|
||||
@@ -225,7 +229,7 @@ pub fn logspace<F: FloatExt>(start: F, end: F, steps: F::Int) -> impl Iterator<I
|
||||
steps = steps.min(between); // At maximum, one step per ULP
|
||||
|
||||
let mut x = start;
|
||||
(0..=steps.cast()).map(move |_| {
|
||||
(F::Int::ZERO..=steps).map(move |_| {
|
||||
let ret = x;
|
||||
x = x.n_up(spacing);
|
||||
ret
|
||||
|
||||
Reference in New Issue
Block a user