Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #121694 > unrolled thread

a MSVC and glibc-compatible fmod()

Started byBonita Montero <Bonita.Montero@gmail.com>
First post2025-02-24 11:48 +0100
Last post2025-03-09 14:56 +0200
Articles 20 on this page of 134 — 8 participants

Back to article view | Back to comp.lang.c++


Contents

  a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-24 11:48 +0100
    Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-24 12:00 +0000
      Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-24 13:48 +0100
        Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-24 13:09 +0000
          Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-24 14:22 +0100
            Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-24 17:13 +0200
              Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-24 16:19 +0100
                Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-24 17:52 +0200
                  Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-25 09:09 +0100
                    Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-25 16:17 +0100
                    Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-25 17:26 +0200
                      Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-25 16:45 +0100
                        Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-25 16:57 +0100
                        Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-25 19:17 +0200
                          Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-25 18:58 +0100
                            Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-26 00:36 +0200
                              Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-26 04:15 +0100
                              Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-26 08:16 +0000
                                Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-26 14:27 +0200
                                  Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-26 14:39 +0000
                                    FP_CONTRACT was : a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-28 16:28 +0200
                                      Re: FP_CONTRACT was : a MSVC and glibc-compatible fmod() Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-03-01 08:35 -0800
          Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-24 16:22 +0200
            Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-24 15:10 +0000
              Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-24 17:33 +0200
                Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-24 16:48 +0000
    Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-02-24 22:21 +0000
      Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-25 07:37 +0100
        Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-02-25 23:03 +0000
          Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-26 02:00 +0200
          Re: a MSVC and glibc-compatible fmod() Wuns Haerst <Wuns.Haerst@wurstfabrik.at> - 2025-02-26 04:01 +0100
      Re: a MSVC and glibc-compatible fmod() Muttley@DastardlyHQ.org - 2025-02-25 08:24 +0000
    Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-02-27 21:16 +0000
      Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-28 07:59 +0100
      Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-02-28 12:35 +0200
        Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-02-28 18:12 +0000
      Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-28 19:23 +0100
    Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-02-28 18:30 +0000
      Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-28 19:31 +0100
        Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-02-28 19:47 +0000
          Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-02-28 20:49 +0100
            Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-03-01 14:37 +0000
              Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-01 16:58 +0100
                Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-03-01 17:11 +0000
                  Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-01 21:02 +0100
                    Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-03-01 20:32 +0000
                      Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-01 21:37 +0100
                        Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-03-01 20:45 +0000
                  Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 09:40 +0100
    Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-01 22:55 +0200
      Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 18:54 +0200
        Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 17:59 +0100
    Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 15:41 +0200
      Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 17:10 +0100
        Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-03-02 16:22 +0000
          Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 17:26 +0100
            Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 19:07 +0200
              Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 18:09 +0100
                Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 18:11 +0100
                  Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 19:52 +0200
                    Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 18:55 +0100
                      Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 20:09 +0200
                        Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 19:14 +0100
                        Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 19:57 +0100
                          Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 22:58 +0200
                            Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-03 12:52 +0100
                              Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-03 18:10 +0200
                                Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-03 23:55 +0200
                                Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-07 09:51 +0100
                          Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-03 18:20 +0200
                            Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-03 17:30 +0100
                              Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-03 19:27 +0200
                                Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-03 18:39 +0100
                      Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-03 02:01 +0200
          Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 19:37 +0200
            Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 18:41 +0100
              Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-02 20:00 +0200
                Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-02 19:01 +0100
        Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 01:31 +0200
          Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 07:41 +0100
            Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 11:08 +0200
              Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 10:31 +0100
                Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 11:46 +0200
                  Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 10:54 +0100
                    Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 12:09 +0200
                      Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 11:21 +0100
                        Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 14:09 +0200
                          Re: a MSVC and glibc-compatible fmod() Mr Flibble <leigh@i42.co.uk> - 2025-03-09 15:26 +0000
                            Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 17:02 +0100
                              Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 19:55 +0200
                                Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 19:10 +0100
                                  Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 19:27 +0100
                          Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 17:23 +0100
                            Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 20:04 +0200
                              Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 19:11 +0100
                                Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 20:11 +0100
                              Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 07:24 +0100
                                Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 10:46 +0100
                                  Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 14:26 +0200
                                    Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 13:45 +0100
                                      Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 16:33 +0200
                                        Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 15:46 +0100
                                          Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 16:59 +0200
                                            Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 16:11 +0100
                                              Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 17:43 +0200
                                                Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 17:13 +0100
                                                  Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 19:51 +0200
                                                    Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 19:00 +0100
                                                      Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 20:38 +0200
                                                        Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 22:34 +0100
                                                          Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 22:36 +0100
                                                            Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 12:47 +0200
                                                        Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 23:52 +0100
                                                          Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 23:57 +0100
                                                            Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-11 09:34 +0100
                                                              Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 12:29 +0200
                                                                Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-11 12:12 +0100
                                                                  Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 13:34 +0200
                                                                    Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-11 13:10 +0100
                                                                      Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 14:55 +0200
                                                                        Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-11 14:08 +0100
                                                                        Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 15:46 +0200
                                                                  Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 13:51 +0200
                                                                Re: a MSVC and glibc-compatible fmod() James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-03-11 14:21 -0400
                                                        Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-11 20:28 +0200
                                                          Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-16 13:48 +0200
                                Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-10 13:17 +0200
                                  Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 12:53 +0100
                                  Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-10 12:54 +0100
                Re: a MSVC and glibc-compatible fmod() wij <wyniijj5@gmail.com> - 2025-03-09 18:51 +0800
                  Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 12:56 +0100
                    Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 14:23 +0200
                      Re: a MSVC and glibc-compatible fmod() Bonita Montero <Bonita.Montero@gmail.com> - 2025-03-09 13:39 +0100
                        Re: a MSVC and glibc-compatible fmod() Michael S <already5chosen@yahoo.com> - 2025-03-09 14:56 +0200

Page 3 of 7 — ← Prev page 1 2 [3] 4 5 6 7  Next page →


#121735

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-02-28 20:49 +0100
Message-ID<vpt40g$3qerg$1@raubtier-asyl.eternal-september.org>
In reply to#121734
Am 28.02.2025 um 20:47 schrieb Mr Flibble:

> IEEE 754 does not define how std::fmod should behave, only
> std::remainder.

There's only one way to do it for finite numbers.

[toc] | [prev] | [next] | [standalone]


#121736

FromMr Flibble <leigh@i42.co.uk>
Date2025-03-01 14:37 +0000
Message-ID<ip66sj989o1fh7ac075qkk28eprau21uoe@4ax.com>
In reply to#121735
On Fri, 28 Feb 2025 20:49:38 +0100, Bonita Montero
<Bonita.Montero@gmail.com> wrote:

>Am 28.02.2025 um 20:47 schrieb Mr Flibble:
>
>> IEEE 754 does not define how std::fmod should behave, only
>> std::remainder.
>
>There's only one way to do it for finite numbers.

Not true as there is a fixed mantissa size, so finite precision,
making your test case useless if x is sufficiently large.

/Flibble

[toc] | [prev] | [next] | [standalone]


#121737

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-03-01 16:58 +0100
Message-ID<vpvarp$9n41$1@raubtier-asyl.eternal-september.org>
In reply to#121736
Am 01.03.2025 um 15:37 schrieb Mr Flibble:
> On Fri, 28 Feb 2025 20:49:38 +0100, Bonita Montero
> <Bonita.Montero@gmail.com> wrote:
> 
>> Am 28.02.2025 um 20:47 schrieb Mr Flibble:
>>
>>> IEEE 754 does not define how std::fmod should behave, only
>>> std::remainder.
>>
>> There's only one way to do it for finite numbers.
> 
> Not true as there is a fixed mantissa size, so finite precision,
> making your test case useless if x is sufficiently large.

The way to do a modolo calculations for every floating point value
except inf or nan (finite numbers) is always the same for all imple-
mentations. And correct implementations are always without precision
los, i.e. exact.
As I've shown solutions like yours are only 50% exact and in 2% they
generate out of range results.

[toc] | [prev] | [next] | [standalone]


#121739

FromMr Flibble <leigh@i42.co.uk>
Date2025-03-01 17:11 +0000
Message-ID<frf6sjtsdk10tc6bha754jmeb1748ph088@4ax.com>
In reply to#121737
On Sat, 1 Mar 2025 16:58:51 +0100, Bonita Montero
<Bonita.Montero@gmail.com> wrote:

>Am 01.03.2025 um 15:37 schrieb Mr Flibble:
>> On Fri, 28 Feb 2025 20:49:38 +0100, Bonita Montero
>> <Bonita.Montero@gmail.com> wrote:
>> 
>>> Am 28.02.2025 um 20:47 schrieb Mr Flibble:
>>>
>>>> IEEE 754 does not define how std::fmod should behave, only
>>>> std::remainder.
>>>
>>> There's only one way to do it for finite numbers.
>> 
>> Not true as there is a fixed mantissa size, so finite precision,
>> making your test case useless if x is sufficiently large.
>
>The way to do a modolo calculations for every floating point value
>except inf or nan (finite numbers) is always the same for all imple-
>mentations. And correct implementations are always without precision
>los, i.e. exact.
>As I've shown solutions like yours are only 50% exact and in 2% they
>generate out of range results.

Thus you are asserting that all finite numbers have an exact IEEE 754
floating point representation which is of course an erroneous
assertion ergo your solution is bogus.

/Flibble

[toc] | [prev] | [next] | [standalone]


#121741

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-03-01 21:02 +0100
Message-ID<vpvp4k$caas$1@raubtier-asyl.eternal-september.org>
In reply to#121739
Am 01.03.2025 um 18:11 schrieb Mr Flibble:

> Thus you are asserting that all finite numbers have an exact IEEE 754
> floating point representation ...

But the result of floating-point operations usually have precision-loss;
except fmod(), which is always correct - when implemented properly. You
didn't implement it correctly.

[toc] | [prev] | [next] | [standalone]


#121742

FromMr Flibble <leigh@i42.co.uk>
Date2025-03-01 20:32 +0000
Message-ID<qmr6sj5fng9t8rups63vcbccus5b717kvr@4ax.com>
In reply to#121741
On Sat, 1 Mar 2025 21:02:32 +0100, Bonita Montero
<Bonita.Montero@gmail.com> wrote:

>Am 01.03.2025 um 18:11 schrieb Mr Flibble:
>
>> Thus you are asserting that all finite numbers have an exact IEEE 754
>> floating point representation ...
>
>But the result of floating-point operations usually have precision-loss;
>except fmod(), which is always correct - when implemented properly. You
>didn't implement it correctly.

False, see my other post.

/Flibble

[toc] | [prev] | [next] | [standalone]


#121743

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-03-01 21:37 +0100
Message-ID<vpvr5j$clb4$1@raubtier-asyl.eternal-september.org>
In reply to#121742
Am 01.03.2025 um 21:32 schrieb Mr Flibble:
> On Sat, 1 Mar 2025 21:02:32 +0100, Bonita Montero
> <Bonita.Montero@gmail.com> wrote:
> 
>> Am 01.03.2025 um 18:11 schrieb Mr Flibble:
>>
>>> Thus you are asserting that all finite numbers have an exact IEEE 754
>>> floating point representation ...
>>
>> But the result of floating-point operations usually have precision-loss;
>> except fmod(), which is always correct - when implemented properly. You
>> didn't implement it correctly.
> 
> False, see my other post.
> 
> /Flibble

This:

#include <iostream>
#include <cmath>
#include <random>
#include <bit>

using namespace std;

double my_fmod( double x, double y );

int main()
{
     mt19937_64 mt;
     uniform_int_distribution<uint64_t> gen( 1, 0x7FEFFFFFFFFFFFFFu );
     size_t imprecise = 0, outOfRange = 0;
     for( size_t r = 1'000'000; r; --r )
     {
         double
             a = bit_cast<double>( gen( mt ) ),
             b = bit_cast<double>( gen( mt ) ),
             fm = fmod( a, b ),
             tfm = my_fmod( a, b );
         imprecise += fm != tfm;
         outOfRange += tfm >= b;
     }
     auto print = []( char const *what, size_t n ) { cout << what << 
(ptrdiff_t)n / (1.0e6 / 100) << "%" << endl; };
     print( "imprecise: ", imprecise );
     print( "out of range: ", outOfRange );
}

double my_fmod( double x, double y )
{
	if( y == 0.0 )
		return x / y;
	return x - std::trunc( x / y ) * y;
}

... prints this ...

imprecise: 49.9096%
out of range: 2.0039%

So your solution is unusable.

[toc] | [prev] | [next] | [standalone]


#121744

FromMr Flibble <leigh@i42.co.uk>
Date2025-03-01 20:45 +0000
Message-ID<les6sj1r101sm87t350peqho57qcec2e86@4ax.com>
In reply to#121743
On Sat, 1 Mar 2025 21:37:10 +0100, Bonita Montero
<Bonita.Montero@gmail.com> wrote:

>Am 01.03.2025 um 21:32 schrieb Mr Flibble:
>> On Sat, 1 Mar 2025 21:02:32 +0100, Bonita Montero
>> <Bonita.Montero@gmail.com> wrote:
>> 
>>> Am 01.03.2025 um 18:11 schrieb Mr Flibble:
>>>
>>>> Thus you are asserting that all finite numbers have an exact IEEE 754
>>>> floating point representation ...
>>>
>>> But the result of floating-point operations usually have precision-loss;
>>> except fmod(), which is always correct - when implemented properly. You
>>> didn't implement it correctly.
>> 
>> False, see my other post.
>> 
>> /Flibble
>
>This:
>
>#include <iostream>
>#include <cmath>
>#include <random>
>#include <bit>
>
>using namespace std;
>
>double my_fmod( double x, double y );
>
>int main()
>{
>     mt19937_64 mt;
>     uniform_int_distribution<uint64_t> gen( 1, 0x7FEFFFFFFFFFFFFFu );
>     size_t imprecise = 0, outOfRange = 0;
>     for( size_t r = 1'000'000; r; --r )
>     {
>         double
>             a = bit_cast<double>( gen( mt ) ),
>             b = bit_cast<double>( gen( mt ) ),
>             fm = fmod( a, b ),
>             tfm = my_fmod( a, b );
>         imprecise += fm != tfm;
>         outOfRange += tfm >= b;
>     }
>     auto print = []( char const *what, size_t n ) { cout << what << 
>(ptrdiff_t)n / (1.0e6 / 100) << "%" << endl; };
>     print( "imprecise: ", imprecise );
>     print( "out of range: ", outOfRange );
>}
>
>double my_fmod( double x, double y )
>{
>	if( y == 0.0 )
>		return x / y;
>	return x - std::trunc( x / y ) * y;
>}
>
>... prints this ...
>
>imprecise: 49.9096%
>out of range: 2.0039%
>
>So your solution is unusable.

False, see my other post.

/Flibble

[toc] | [prev] | [next] | [standalone]


#121750

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-03-02 09:40 +0100
Message-ID<vq15i7$n09t$1@raubtier-asyl.eternal-september.org>
In reply to#121739
Am 01.03.2025 um 18:11 schrieb Mr Flibble:

> Thus you are asserting that all finite numbers have an exact IEEE 754
> floating point representation ...

I never said that.

[toc] | [prev] | [next] | [standalone]


#121745

FromMichael S <already5chosen@yahoo.com>
Date2025-03-01 22:55 +0200
Message-ID<20250301225559.00000d4e@yahoo.com>
In reply to#121694
On Mon, 24 Feb 2025 11:48:08 +0100
Bonita Montero <Bonita.Montero@gmail.com> wrote:

> I wanted to optimize fmod to be a bit faster. This is my C++20
> solution.
> 
> double myFmod( double x, double y )
> {
> 	constexpr uint64_t
> 		SIGN = 1ull << 63,
> 		IMPLICIT = 1ull << 52,
> 		MANT = IMPLICIT - 1,
> 		QBIT = 1ull << 51;
> 	uint64_t const
> 		binX = bit_cast<uint64_t>( x ),
> 		binY = bit_cast<uint64_t>( y );
> 	static auto abs = []( uint64_t m ) { return m & ~SIGN; };
> 	auto isNaN = []( uint64_t m ) { return abs( m ) >=
> 0x7FF0000000000001u; }; auto isSig = []( uint64_t m ) { return !(m &
> QBIT); }; if( isNaN( binX ) ) [[unlikely]] // x == NaN
> #if defined(_MSC_VER)
> 		return bit_cast<double>( isNaN( binY ) ? binY | binX
> & binY & QBIT : binX );
> #else
> 	{
> 		if( isSig( binX ) || isNaN( binY ) && isSig( binY ) )
> [[unlikely]] feraiseexcept( FE_INVALID );
> 		return bit_cast<double>( binX | QBIT );
> 	}
> #endif
> 	if( isNaN( binY ) ) [[unlikely]] // x != NaN || y == NaN
> #if defined(_MSC_VER)
> 		return y;
> #else
> 	{
> 		if( isSig( binY ) ) [[unlikely]]
> 			feraiseexcept( FE_INVALID );
> 		return bit_cast<double>( binY | QBIT );
> 	}
> #endif
> 	auto isInf = []( uint64_t m ) { return abs( m ) ==
> 0x7FF0000000000000u; }; if( isInf( binX ) ) // x == Inf
> 	{
> 		feraiseexcept( FE_INVALID );
> #if defined(_MSC_VER)
> 		return bit_cast<double>( binX & ~MANT | QBIT );
> #else
> 		return -numeric_limits<double>::quiet_NaN();
> #endif
> 	}
> 	if( !abs( binY ) ) [[unlikely]] // y == 0
> 	{
> 		feraiseexcept( FE_INVALID );
> #if defined(_MSC_VER)
> 		return numeric_limits<double>::quiet_NaN();
> #else
> 		return -numeric_limits<double>::quiet_NaN();
> #endif
> 	}
> 	if( !abs( binX ) || isInf( binY ) ) [[unlikely]] // x == 0 ||
> y == Inf return x;
> 	auto exp = []( uint64_t b ) -> int { return b >> 52 & 0x7FF;
> }; int
> 		expX = exp( binX ),
> 		expY = exp( binY );
> 	auto mant = []( uint64_t b ) { return b & MANT; };
> 	uint64_t
> 		mantX = mant( binX ),
> 		mantY = mant( binY );
> 	static auto normalize = []( int &exp, uint64_t &mant )
> 	{
> 		unsigned shift = countl_zero( mant ) - 11;
> 		mant <<= shift;
> 		exp -= shift;
> 	};
> 	auto build = []( int &exp, uint64_t &mant )
> 	{
> 		if( exp ) [[likely]]
> 			mant |= IMPLICIT;
> 		else
> 		{
> 			exp = 1;
> 			normalize( exp, mant );
> 		}
> 	};
> 	build( expX, mantX );
> 	build( expY, mantY );
> 	uint64_t signX = binX & SIGN;
> 	int expDiff;
> 	while( (expDiff = expX - expY) > 0 )
> 	{
> 		unsigned bits = expDiff <= 11 ? expDiff : 11;
> 		if( !(mantX = (mantX << bits) % mantY) ) [[unlikely]]
> 			return bit_cast<double>( signX );
> 		expX -= bits;
> 		normalize( expX, mantX );
> 	}
> 	if( !expDiff && mantX >= mantY ) [[unlikely]]
> 		if( (mantX -= mantY) ) [[likely]]
> 			normalize( expX, mantX );
> 		else
> 			return bit_cast<double>( signX );
> 	if( expX <= 0 ) [[unlikely]]
> 	{
> 		assert(expX >= -51);
> 		mantX = mantX >> (unsigned)(-expX + 1);
> 		expX = 0;
> 	}
> 	return bit_cast<double>( signX | (uint64_t)expX << 52 | mantX
> & MANT ); }
> 
> It's about six times faster than the glibc 2.31 solution in my
> benchmark. The returned NaNs and the raised exceptions are MSVC-
> and glibc-compatible.
> 

How about that?
Pay attention, it's C rather than C++. So 5 times shorter :-)
It's not the fastest for big x/y ratios, but rather simple and not
*too* slow. At least as long as hardware supports FMA.
For small x/y ratios it should be pretty close to best possible.


#include <math.h>
#include <fenv.h>

double my_fmod(double x, double y)
{
  if (isnan(x))
    return x;

  // pre-process y
  if (isless(y, 0))
   y = -y;
  else if (isgreater(y, 0))
   ;
  else {
    if (isnan(y))
      return y;
    // y==0
    feraiseexcept(FE_INVALID);
    return nan("y0");
  }

  // y in (0:+inf]

  // Quick path
  double xx = x * 0x1p-53;
  if (xx > -y && xx < y) {
    // among other things, x guaranteed to be finite
    if (x > -y && x < y)
       return x; // case y=+-inf covered here
    double d = trunc(x/y);
    double res = fma(-y, d, x);
    if (signbit(x) != signbit(res)) {
      // overshoot because of unfortunate division rounding
      // it is extremely rare for small x/y,
      // but not rare when x/y is close to 2**53
      res =  fma(-y, d+(signbit(x)*2-1), x);
    }
    return res;
  }

  // slow path
  if (isinf(x)) {
    feraiseexcept(FE_INVALID);
    return nan("xinf");
  }

  int oldRnd = fegetround();
  fesetround(FE_TOWARDZERO);

  double ax = fabs(x);
  do {
    double yy = y;
    while (yy < ax * 0x1p-1022)
      yy *= 0x1p1021;

    do
      ax = fma(-yy, trunc(ax/yy), ax);
    while (ax >= yy);

  } while (ax >= y);

  ax = copysign(ax, x);
  fesetround(oldRnd);
  return ax;
}


[toc] | [prev] | [next] | [standalone]


#121764

FromMichael S <already5chosen@yahoo.com>
Date2025-03-02 18:54 +0200
Message-ID<20250302185414.000047b4@yahoo.com>
In reply to#121745
On Sat, 1 Mar 2025 22:55:59 +0200
Michael S <already5chosen@yahoo.com> wrote:

> On Mon, 24 Feb 2025 11:48:08 +0100
> Bonita Montero <Bonita.Montero@gmail.com> wrote:
> 
> > I wanted to optimize fmod to be a bit faster. This is my C++20
> > solution.
> > 
> 
> How about that?
> Pay attention, it's C rather than C++. So 5 times shorter :-)
> It's not the fastest for big x/y ratios, but rather simple and not
> *too* slow. At least as long as hardware supports FMA.
> For small x/y ratios it should be pretty close to best possible.
> 

I didn't RTFM about signbit() and didn't check with compilers others
than clang, so didn't pay attention to the bug until testing with
MSVC. At the same opportunity I looked at MSVC-generated asm and found
out that it does not inline trunc() and copysign(). So, I changed the
code please MSVC idiosyncrasy, replacing trunc() with floor() and using
if () instead of copysign(). Fortunately, the changes didn't make
clang/gcc compiled code any slower.

Here is hopefully correct version:

#include <math.h>
#include <fenv.h>

double my_fmod(double x, double y)
{
  if (isnan(x))
    return x;

  // pre-process y
  if (y < 0)
   y = -y;
  else if (y > 0)
   ;
  else {
    if (isnan(y))
      return y;
    // y==0
    feraiseexcept(FE_INVALID);
    return NAN;
  }

  // y in (0:+inf]
  double ax = fabs(x);

  // Quick path
  double xx = ax * 0x1p-53;
  if (xx < y) {
    // among other things, x guaranteed to be finite
    if (ax < y)
       return x; // case y=+-inf covered here
    double d = floor(ax/y);
    double res = fma(-y, d, ax);
    if (res < 0) {
      // overshoot because of unfortunate division rounding
      // it is extremely rare for small x/y,
      // but not rare when x/y is close to 2**53
      res = fma(-y, d-1, ax);
    }
    if (x < 0)
      res = -res;
    return res;
  }

  // slow path
  if (isinf(x)) {
    feraiseexcept(FE_INVALID);
    return NAN;
  }

  int oldRnd = fegetround();
  fesetround(FE_TOWARDZERO);

  do {
    double yy = y;
    while (yy < ax * 0x1p-1022)
      yy *= 0x1p1021;

    do
      ax = fma(-yy, floor(ax/yy), ax);
    while (ax >= yy);

  } while (ax >= y);

  if (x < 0)
    ax = -ax;
  fesetround(oldRnd);
  return ax;
}


The behaviour w.r.t. raising FE_INVALID when either x or y is signaling
NaN could differ from library implementation, but as far as I understand
both raising and not raising exception in this case is legal.

This code is between 15-20% slower then standard library for clang and
gcc, and 0 to 15% faster then standard library for MSVC, so of no
practical interest.

Still, it is better than Bonita's in all possible circumstances.

[toc] | [prev] | [next] | [standalone]


#121767

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-03-02 17:59 +0100
Message-ID<vq22ou$rve6$1@raubtier-asyl.eternal-september.org>
In reply to#121764
Am 02.03.2025 um 17:54 schrieb Michael S:

> Still, it is better than Bonita's in all possible circumstances.

Not better than my latest code with MSVC.

[toc] | [prev] | [next] | [standalone]


#121753

FromMichael S <already5chosen@yahoo.com>
Date2025-03-02 15:41 +0200
Message-ID<20250302154155.000021c6@yahoo.com>
In reply to#121694
On Mon, 24 Feb 2025 11:48:08 +0100
Bonita Montero <Bonita.Montero@gmail.com> wrote:

> I wanted to optimize fmod to be a bit faster. This is my C++20
> solution.
> 
> 
> It's about six times faster than the glibc 2.31 solution in my
> benchmark. The returned NaNs and the raised exceptions are MSVC-
> and glibc-compatible.
> 

Here are my benchmark results on Windows/msys2, 4.25MHz Skylake:
Compiler  x/y range            fmod  my_fmod (yours)
clang     [0.5:2**53]           5.6     38.0
gcc       [0.5:2**53]           5.8     36.7
MSVC      [0.5:2**53]          11.0     36.8
clang     [2**-2098:2**2098]  102.9    294.3
gcc       [2**-2098:2**2098]  102.9    291.7  
MSVC      [2**-2098:2**2098]  109.9    289.6

Your variant is 2.6x to 6.8x times slower than standard library.

My variant is also slower than standard library, but the margin of
defeat is much closer.

------- first range
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cfenv>
#include <vector>
#include <random>
#include <chrono>

double my_fmod(double x, double y);

int main(void)
{
  const int VEC_LEN = 100000;
  const int N_IT    = 31;

  std::vector<double> xy(VEC_LEN*2);
  std::mt19937_64 rndGen;
  const uint64_t EXP_MASK = 2047ull << 52;
  for (int i = 0; i < VEC_LEN*2; ++i) {
    uint64_t u = rndGen();
    uint64_t exp = 1023;
    if (i % 2 == 0) { // x
      uint64_t exp0 = (u >> 52) & 2047;
      exp += exp0 % 52;
    }
    u = (u & ~EXP_MASK) | (exp << 52);
    double d;
    memcpy(&d, &u, sizeof(d));
    xy[i] = d;
  }
  std::vector<double> res(VEC_LEN);
  std::vector<double> ref(VEC_LEN);

  auto t00 = std::chrono::steady_clock::now();
  const double* pXY = xy.data();
  double* pRef = ref.data();
  double* pRes = res.data();
  std::vector<int64_t> tref(N_IT);
  std::vector<int64_t> tres(N_IT);
  for (int it = 0; it < N_IT; ++it) {
    auto t0 = std::chrono::steady_clock::now();
    for (int i = 0; i < VEC_LEN; ++i)
      pRef[i] = fmod(pXY[i*2+0], pXY[i*2+1]);
    auto t1 = std::chrono::steady_clock::now();
    for (int i = 0; i < VEC_LEN; ++i)
      pRes[i] = my_fmod(pXY[i*2+0], pXY[i*2+1]);
    auto t2 = std::chrono::steady_clock::now();

    tref[it] = std::chrono::duration_cast<std::chrono::nanoseconds>(t1
    - t0).count();
    tres[it] = std::chrono::duration_cast<std::chrono::nanoseconds>(t2
    - t1).count();

    for (int i = 0; i < VEC_LEN; ++i) {
      if (pRef[i] != pRes[i]) {
        if (!std::isnan(pRef[i]) || !std::isnan(pRes[i])) {
          printf(
            "Mismatch. fmod(%.17e, %.17e).\n"
            "ref %.17e\n"
            "my  %.17e\n"
            ,xy[i*2+0]
            ,xy[i*2+1]
            ,ref[i]
            ,res[i]
          );
          return 1;
        }
      }
    }
  }

  auto t11 = std::chrono::steady_clock::now();
  int64_t dt = std::chrono::duration_cast<std::chrono::nanoseconds>(t11
  - t00).count();

  std::nth_element(tref.begin(), tref.begin()+N_IT/2, tref.end());
  std::nth_element(tres.begin(), tres.begin()+N_IT/2, tres.end());
  printf("fmod %.2f nsec. my_fmod %.2f nsec. Test time %.3f msec\n"
    ,double(tref[N_IT/2]) / VEC_LEN
    ,double(tres[N_IT/2]) / VEC_LEN
    ,double(dt)*1e-6
  );

  return 0;
}


-- second range
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cfenv>
#include <vector>
#include <random>
#include <chrono>

double my_fmod(double x, double y);

int main(void)
{
  const int VEC_LEN = 100000;
  const int N_IT    = 31;

  std::vector<double> xy(VEC_LEN*2);
  std::mt19937_64 rndGen;
  for (int i = 0; i < VEC_LEN*2; ++i) {
    uint64_t u = rndGen();
    double d;
    memcpy(&d, &u, sizeof(d));
    xy[i] = d;
  }
  std::vector<double> res(VEC_LEN);
  std::vector<double> ref(VEC_LEN);

  auto t00 = std::chrono::steady_clock::now();
  const double* pXY = xy.data();
  double* pRef = ref.data();
  double* pRes = res.data();
  std::vector<int64_t> tref(N_IT);
  std::vector<int64_t> tres(N_IT);
  for (int it = 0; it < N_IT; ++it) {
    auto t0 = std::chrono::steady_clock::now();
    for (int i = 0; i < VEC_LEN; ++i)
      pRef[i] = fmod(pXY[i*2+0], pXY[i*2+1]);
    auto t1 = std::chrono::steady_clock::now();
    for (int i = 0; i < VEC_LEN; ++i)
      pRes[i] = my_fmod(pXY[i*2+0], pXY[i*2+1]);
    auto t2 = std::chrono::steady_clock::now();

    tref[it] = std::chrono::duration_cast<std::chrono::nanoseconds>(t1
    - t0).count();
    tres[it] = std::chrono::duration_cast<std::chrono::nanoseconds>(t2
    - t1).count();

    for (int i = 0; i < VEC_LEN; ++i) {
      if (pRef[i] != pRes[i]) {
        if (!std::isnan(pRef[i]) || !std::isnan(pRes[i])) {
          printf(
            "Mismatch. fmod(%.17e, %.17e).\n"
            "ref %.17e\n"
            "my  %.17e\n"
            ,xy[i*2+0]
            ,xy[i*2+1]
            ,ref[i]
            ,res[i]
          );
          return 1;
        }
      }
    }
  }

  auto t11 = std::chrono::steady_clock::now();
  int64_t dt = std::chrono::duration_cast<std::chrono::nanoseconds>(t11
  - t00).count();

  std::nth_element(tref.begin(), tref.begin()+N_IT/2, tref.end());
  std::nth_element(tres.begin(), tres.begin()+N_IT/2, tres.end());
  printf("fmod %.2f nsec. my_fmod %.2f nsec. Test time %.3f msec\n"
    ,double(tref[N_IT/2]) / VEC_LEN
    ,double(tres[N_IT/2]) / VEC_LEN
    ,double(dt)*1e-6
  );

  return 0;
}



 

[toc] | [prev] | [next] | [standalone]


#121761

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-03-02 17:10 +0100
Message-ID<vq1vtq$rf5j$1@raubtier-asyl.eternal-september.org>
In reply to#121753
This is my code, improved by the _udiv128-intrinsic of MSVC which
provides a 128 / 64 division. With that my algorithm becomes nearly
tree times as fast as before. I'll provide a g++ / clang++ compatible
version with inline-assembly later.

template<bool _32 = false>
double xMyFmod( double x, double y )
{
	constexpr uint64_t
		SIGN = 1ull << 63,
		IMPLICIT = 1ull << 52,
		MANT = IMPLICIT - 1,
		QBIT = 1ull << 51;
	uint64_t const
		binX = bit_cast<uint64_t>( x ),
		binY = bit_cast<uint64_t>( y );
	static auto abs = []( uint64_t m ) { return m & ~SIGN; };
	auto isNaN = []( uint64_t m ) { return abs( m ) >= 0x7FF0000000000001u; };
	auto isSig = []( uint64_t m ) { return !(m & QBIT); };
	if( isNaN( binX ) ) [[unlikely]] // x == NaN
#if defined(_MSC_VER)
		return bit_cast<double>( isNaN( binY ) ? binY | binX & binY & QBIT : 
binX );
#else
	{
		if( isSig( binX ) || isNaN( binY ) && isSig( binY ) ) [[unlikely]]
			feraiseexcept( FE_INVALID );
		return bit_cast<double>( binX | QBIT );
	}
#endif
	auto isInf = []( uint64_t m ) { return abs( m ) == 0x7FF0000000000000u; };
	if( isNaN( binY ) ) [[unlikely]] // x != NaN || y == NaN
#if defined(_MSC_VER)
	{
		if constexpr( _32 )
			if( isInf( binX ) )
				feraiseexcept( FE_INVALID );
		return y;
	}
#else
	{
		if( isSig( binY ) ) [[unlikely]]
			feraiseexcept( FE_INVALID );
		return bit_cast<double>( binY | QBIT );
	}
#endif
	if( isInf( binX ) ) // x == Inf
	{
		feraiseexcept( FE_INVALID );
#if defined(_MSC_VER)
		return bit_cast<double>( binX & ~MANT | QBIT );
#else
		return -numeric_limits<double>::quiet_NaN();
#endif
	}
	if( !abs( binY ) ) [[unlikely]] // y == 0
	{
		feraiseexcept( FE_INVALID );
#if defined(_MSC_VER)
		return numeric_limits<double>::quiet_NaN();
#else
		return -numeric_limits<double>::quiet_NaN();
#endif
	}
	if( !abs( binX ) || isInf( binY ) ) [[unlikely]] // x == 0 || y == Inf
		return x;
	auto exp = []( uint64_t b ) -> int { return b >> 52 & 0x7FF; };
	int
		expX = exp( binX ),
		expY = exp( binY );
	auto mant = []( uint64_t b ) { return b & MANT; };
	uint64_t
		mantX = mant( binX ),
		mantY = mant( binY );
	int headBits = 11;
	static auto normalize = [&]( int &exp, uint64_t &mant )
	{
		unsigned shift = countl_zero( mant ) - headBits;
		mant <<= shift;
		exp -= shift;
	};
	auto build = []( int &exp, uint64_t &mant )
	{
		if( exp ) [[likely]]
			mant |= IMPLICIT;
		else
		{
			exp = 1;
			normalize( exp, mant );
		}
	};
	build( expX, mantX );
	build( expY, mantY );
	int
		tailX = countr_zero( mantX ),
		tailY = countr_zero( mantY ),
		tailBits = tailX <= tailY ? tailX : tailY;
	headBits += tailBits;
	mantX >>= tailBits;
	mantY >>= tailBits;
	uint64_t signX = binX & SIGN;
	int expDiff;
#if defined(_MSC_VER)
	while( (expDiff = expX - expY) > 63 )
	{
		unsigned long long hi = mantX >> 1, lo = mantX << 63, remainder;
		(void)_udiv128( hi, lo, mantY, &remainder );
		expX -= 63;
		mantX = remainder;
		normalize( expX, mantX );
	}
#endif
	while( (expDiff = expX - expY) > 0 )
	{
		unsigned bits = expDiff <= headBits ? expDiff : headBits;
		if( !(mantX = (mantX << bits) % mantY) ) [[unlikely]]
			return bit_cast<double>( signX );
		expX -= bits;
		normalize( expX, mantX );
	}
	if( !expDiff && mantX >= mantY ) [[unlikely]]
		if( (mantX -= mantY) ) [[likely]]
			normalize( expX, mantX );
		else
			return bit_cast<double>( signX );
	mantX <<= tailBits;
	mantY <<= tailBits;
	if( expX <= 0 ) [[unlikely]]
	{
		assert(expX >= -51);
		mantX = mantX >> (unsigned)(-expX + 1);
		expX = 0;
	}
	return bit_cast<double>( signX | (uint64_t)expX << 52 | mantX & MANT );
}

double myFmod( double x, double y )
{
	return xMyFmod( x, y );
}

inline float myFmod( float x, float y )
{
	return (float)xMyFmod<true>( (double)x, (double)y );
}

[toc] | [prev] | [next] | [standalone]


#121762

FromMr Flibble <leigh@i42.co.uk>
Date2025-03-02 16:22 +0000
Message-ID<qc19sjl96hsj4nacc82q16i0tmjjc33mmo@4ax.com>
In reply to#121761
On Sun, 2 Mar 2025 17:10:37 +0100, Bonita Montero
<Bonita.Montero@gmail.com> wrote:

>This is my code, improved by the _udiv128-intrinsic of MSVC which
>provides a 128 / 64 division. With that my algorithm becomes nearly
>tree times as fast as before. I'll provide a g++ / clang++ compatible
>version with inline-assembly later.
>
Still slow tho.

/Flibble

[toc] | [prev] | [next] | [standalone]


#121763

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-03-02 17:26 +0100
Message-ID<vq20r6$rjs5$1@raubtier-asyl.eternal-september.org>
In reply to#121762
Am 02.03.2025 um 17:22 schrieb Mr Flibble:
> On Sun, 2 Mar 2025 17:10:37 +0100, Bonita Montero
> <Bonita.Montero@gmail.com> wrote:
> 
>> This is my code, improved by the _udiv128-intrinsic of MSVC which
>> provides a 128 / 64 division. With that my algorithm becomes nearly
>> tree times as fast as before. I'll provide a g++ / clang++ compatible
>> version with inline-assembly later.
>>
> Still slow tho.

With MSVC and the fairer random numbers I chose I'm 2.5 times
faster.

[toc] | [prev] | [next] | [standalone]


#121768

FromMichael S <already5chosen@yahoo.com>
Date2025-03-02 19:07 +0200
Message-ID<20250302190759.00003e0a@yahoo.com>
In reply to#121763
On Sun, 2 Mar 2025 17:26:18 +0100
Bonita Montero <Bonita.Montero@gmail.com> wrote:

> 
> With MSVC and the fairer random numbers I chose I'm 2.5 times
> faster.
> 

I don't trust your benchmarking skills.

[toc] | [prev] | [next] | [standalone]


#121770

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-03-02 18:09 +0100
Message-ID<vq23c9$s2ng$1@raubtier-asyl.eternal-september.org>
In reply to#121768
Am 02.03.2025 um 18:07 schrieb Michael S:
> On Sun, 2 Mar 2025 17:26:18 +0100
> Bonita Montero <Bonita.Montero@gmail.com> wrote:
> 
>>
>> With MSVC and the fairer random numbers I chose I'm 2.5 times
>> faster.
>>
> 
> I don't trust your benchmarking skills.

I don't prefer your fast-path value combinations but I chose 75% random
finite combinations.

[toc] | [prev] | [next] | [standalone]


#121771

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-03-02 18:11 +0100
Message-ID<vq23fe$s3t3$1@raubtier-asyl.eternal-september.org>
In reply to#121770
Am 02.03.2025 um 18:09 schrieb Bonita Montero:
> Am 02.03.2025 um 18:07 schrieb Michael S:
>> On Sun, 2 Mar 2025 17:26:18 +0100
>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>
>>>
>>> With MSVC and the fairer random numbers I chose I'm 2.5 times
>>> faster.
>>>
>>
>> I don't trust your benchmarking skills.
> 
> I don't prefer your fast-path value combinations but I chose 75% random
> finite combinations.
> 

This generates the random values for me:

	mt19937_64 mt;
	uniform_int_distribution<uint64_t>
		genType( 0, 15 ),
		genFinite( 0x0010000000000000u, 0x7FEFFFFFFFFFFFFFu ),
		genDen( 1, 0x000FFFFFFFFFFFFFu ),
		genNaN( 0x7FF0000000000001u, 0x7FFFFFFFFFFFFFFFu );
	auto get = [&]()
	{
		constexpr uint64_t
			FINITE_THRESH = 4, // 75% finites
			ZERO = 3, // 6.25% zeroes
			DENORMALS = 2, // 6.25% denormals
			INF = 1, // 6.25% Infs
			NAN_ = 0; // 6.25% NaNs
		uint64_t
			sign = mt() & - numeric_limits<int64_t>::min(),
			type = genType( mt );
		if( type >= FINITE_THRESH )
			return bit_cast<double>( sign | genFinite( mt ) );
		if( type == ZERO )
			return bit_cast<double>( sign );
		if( type == DENORMALS )
			return bit_cast<double>( sign | genDen( mt ) );
		if( type == INF )
			return bit_cast<double>( sign | 0x7FF0000000000000u );
		assert(type == NAN_);
		return bit_cast<double>( sign | genNaN( mt ) );
	};

[toc] | [prev] | [next] | [standalone]


#121775

FromMichael S <already5chosen@yahoo.com>
Date2025-03-02 19:52 +0200
Message-ID<20250302195221.00005b7f@yahoo.com>
In reply to#121771
On Sun, 2 Mar 2025 18:11:14 +0100
Bonita Montero <Bonita.Montero@gmail.com> wrote:

> Am 02.03.2025 um 18:09 schrieb Bonita Montero:
> > Am 02.03.2025 um 18:07 schrieb Michael S:  
> >> On Sun, 2 Mar 2025 17:26:18 +0100
> >> Bonita Montero <Bonita.Montero@gmail.com> wrote:
> >>  
> >>>
> >>> With MSVC and the fairer random numbers I chose I'm 2.5 times
> >>> faster.
> >>>  
> >>
> >> I don't trust your benchmarking skills.  
> > 
> > I don't prefer your fast-path value combinations but I chose 75%
> > random finite combinations.
> >   
> 
> This generates the random values for me:
> 
> 	mt19937_64 mt;
> 	uniform_int_distribution<uint64_t>
> 		genType( 0, 15 ),
> 		genFinite( 0x0010000000000000u, 0x7FEFFFFFFFFFFFFFu ),
> 		genDen( 1, 0x000FFFFFFFFFFFFFu ),
> 		genNaN( 0x7FF0000000000001u, 0x7FFFFFFFFFFFFFFFu );
> 	auto get = [&]()
> 	{
> 		constexpr uint64_t
> 			FINITE_THRESH = 4, // 75% finites
> 			ZERO = 3, // 6.25% zeroes
> 			DENORMALS = 2, // 6.25% denormals
> 			INF = 1, // 6.25% Infs
> 			NAN_ = 0; // 6.25% NaNs
> 		uint64_t
> 			sign = mt() & -
> numeric_limits<int64_t>::min(), type = genType( mt );
> 		if( type >= FINITE_THRESH )
> 			return bit_cast<double>( sign | genFinite( mt
> ) ); if( type == ZERO )
> 			return bit_cast<double>( sign );
> 		if( type == DENORMALS )
> 			return bit_cast<double>( sign | genDen( mt )
> ); if( type == INF )
> 			return bit_cast<double>( sign |
> 0x7FF0000000000000u ); assert(type == NAN_);
> 		return bit_cast<double>( sign | genNaN( mt ) );
> 	};
> 

Your distribution is very different from what one would expect in
real-world usage.
In real-world usage apart from debugging stage there are no inf, nan or
y=zero. x=zero happens, but with lower probability that 6%. Denormals
also happen, but with even lower probability than x=zero. Also in
majority of real-world scenarios huge x/y ratios either not happen at
all or are extremely rare.





[toc] | [prev] | [next] | [standalone]


Page 3 of 7 — ← Prev page 1 2 [3] 4 5 6 7  Next page →

Back to top | Article view | comp.lang.c++


csiph-web