in reply to Re^5: Comparing a value to a list of numbers
in thread Comparing a value to a list of numbers

> plus I imagine certain set operations would be problematic due to floating-point inaccuracies.
I doubt this, rounding errors happen only after arithmetic operations

I was thinking something like:

$ perl -MSet::IntSpan -le 'print Set::IntSpan->new("1-10")->complement +->run_list' (-0,11-)

What's the equivalent with floating-point? Does the lower range end at 0.9, 0.99, 0.999, 0.9999, ...? I know there's probably a mathematically valid answer, but I wonder how it would be represented as a floating-point number.

Another one:

use Set::IntSpan; my $set = Set::IntSpan->new('3-12,25-30,42'); for ( my $el=$set->first; defined $el; $el=$set->next ) { print "$el\n"; }

Workarounds would be possible, like telling the iterator what size steps it should take.

I'm not the module's author, so I can't tell you any more "why" and "why not" :-) It's probably possible to write a similar module that handles floats, but Set::IntSpan isn't it ;-)

Update: And, of course it's possible to work with decimals if you multiply them by the appropriate factors, like how I work with milliseconds instead of seconds in Determining Gaps and Overlap in Timestamped Data.

Replies are listed 'Best First'.
Re^7: Comparing a value to a list of numbers (updated)
by syphilis (Archbishop) on Feb 02, 2021 at 01:38 UTC
    Does the lower range end at 0.9, 0.99, 0.999, 0.9999, ...?

    Sounds like you would perhaps be looking for a "nextbelow" implementation (and "nextabove" at the other end of the range).
    It's not implemented in core perl, and I'm unaware of any such implementations in any of the core modules, too.
    My own Math::MPFR provides them, and I can also see them in Zefram's pure perl Data::Float module as (nextup/nextdown/nextafter).
    use strict; use warnings; use Config; use Data::Float; # Set $prec to the required value # for "%.*e" formatting for the # nvtype that we have. my $prec = 35; # __float128 # Amend $prec's value as needed if( $Config{nvsize} == 8 ) { $prec = 16 } elsif( $Config{nvtype} eq 'long double' ) { $prec = 20 unless( $Config{longdblkind} == 1 || $Config{longdblkind} == 2 ); } my $val = 1.0; my $down = Data::Float::nextdown( $val ); my $up = Data::Float::nextup ( $val ); printf "%.${prec}e %a\n", $down, $down; printf "%.${prec}e %a\n", $val, $val; printf "%.${prec}e %a\n", $up, $up;
    If nvtype is double, it outputs:
    9.9999999999999989e-01 0x1.fffffffffffffp-1 1.0000000000000000e+00 0x1p+0 1.0000000000000002e+00 0x1.0000000000001p+0
    Cheers,
    Rob
      My own Math::MPFR provides them, and I can also see them in Zefram's pure perl Data::Float module as (nextup/nextdown/nextafter).

      Very useful to know, thank you!

Re^7: Comparing a value to a list of numbers (floats)
by LanX (Saint) on Feb 01, 2021 at 18:36 UTC
    > I know there's probably a mathematically valid answer,

    And that's how I'm thinking (... you know me so well ;-)

    If binary search is used, it's based on numeric comparison.

    The complement of <= is > and the rest is logic.

    > $el=$set->next

    well that's a feature of finite sets° which can't be applied here.

    I'd throw an error in this case.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

    °) to be precise: finite ordered sets