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 2 of 7 — ← Prev page 1 [2] 3 4 5 6 7  Next page →


#121729 — FP_CONTRACT was : a MSVC and glibc-compatible fmod()

FromMichael S <already5chosen@yahoo.com>
Date2025-02-28 16:28 +0200
SubjectFP_CONTRACT was : a MSVC and glibc-compatible fmod()
Message-ID<20250228162832.000033d0@yahoo.com>
In reply to#121723
On Wed, 26 Feb 2025 14:39:34 -0000 (UTC)
Muttley@DastardlyHQ.org wrote:

> On Wed, 26 Feb 2025 14:27:21 +0200
> Michael S <already5chosen@yahoo.com> wibbled:
> >On Wed, 26 Feb 2025 08:16:01 -0000 (UTC)
> >Muttley@DastardlyHQ.org wrote:
> >I played a little on godbolt and it seems that the bug is relatively
> >new. clang 13 still generates correct code. clang 14 does not. I.e.
> >slightly less than 3 years.   
> 
> I don't think they've noticed:
> 
> R8603$ cc --version
> Apple clang version 16.0.0 (clang-1600.0.26.6)
> 

More googling/stack-overflowing.

clang/LLVM people think that it is a feature rather than a bug. They
claim that the standard allows fusing. I think that they are wrong, but
I didn't read the respective part of the standard.

The behavior can be turned back into clang13 way by -ffp-contract=off.
Or with pragma
#pragma STDC FP_CONTRACT OFF


See answer by rici
https://stackoverflow.com/questions/73985098/clang-14-0-0-floating-point-optimizations

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


#121738 — Re: FP_CONTRACT was : a MSVC and glibc-compatible fmod()

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2025-03-01 08:35 -0800
SubjectRe: FP_CONTRACT was : a MSVC and glibc-compatible fmod()
Message-ID<86ikosyaiy.fsf@linuxsc.com>
In reply to#121729
Michael S <already5chosen@yahoo.com> writes:

> On Wed, 26 Feb 2025 14:39:34 -0000 (UTC)
> Muttley@DastardlyHQ.org wrote:
>
>> On Wed, 26 Feb 2025 14:27:21 +0200
>> Michael S <already5chosen@yahoo.com> wibbled:
>>
>>> On Wed, 26 Feb 2025 08:16:01 -0000 (UTC)
>>> Muttley@DastardlyHQ.org wrote:
>>> I played a little on godbolt and it seems that the bug is relatively
>>> new.  clang 13 still generates correct code.  clang 14 does not.  I.e.
>>> slightly less than 3 years.
>>
>> I don't think they've noticed:
>>
>> R8603$ cc --version
>> Apple clang version 16.0.0 (clang-1600.0.26.6)
>
> More googling/stack-overflowing.
>
> clang/LLVM people think that it is a feature rather than a bug.  They
> claim that the standard allows fusing.  I think that they are wrong, but
> I didn't read the respective part of the standard.

My reading of the C standard is that implementations are allowed to
contract floating-point expressions (aka fusing) as their default
choice of what is allowed, and because this default choice falls
into the category of implementation-defined behavior the
implementation must document what default it has chosen.

> The behavior can be turned back into clang13 way by -ffp-contract=off.
> Or with pragma
> #pragma STDC FP_CONTRACT OFF

The C standard doesn't say anything about compiler options.

The C standard does specify what happens for the STDC FP_CONTRACT
standard #pragma, for both

    #pragma STDC FP_CONTRACT OFF

and

    #pragma STDC FP_CONTRACT ON

If you want to look, what these #pragma's do is defined in the
section of the C standard pertaining to <math.h>, which is 7.12 in
the N1256 document for C99.

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


#121699

FromMichael S <already5chosen@yahoo.com>
Date2025-02-24 16:22 +0200
Message-ID<20250224162246.000016c6@yahoo.com>
In reply to#121697
On Mon, 24 Feb 2025 13:09:50 -0000 (UTC)
Muttley@DastardlyHQ.org wrote:

> On Mon, 24 Feb 2025 13:48:02 +0100
> Bonita Montero <Bonita.Montero@gmail.com> wibbled:
> >Am 24.02.2025 um 13:00 schrieb Muttley@DastardlyHQ.org:  
> >> On Mon, 24 Feb 2025 11:48:08 +0100
> >> Bonita Montero <Bonita.Montero@gmail.com> wibbled:  
> >>> I wanted to optimize fmod to be a bit faster. This is my C++20
> >>> solution.
> >>>
> >>> double myFmod( double x, double y )  
> >> [snip]  
> >>>
> >>> 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.  
> >> 
> >> double myFmod(double x, double y)
> >> {
> >>          double div = x / y;
> >>          return y * (div - (long)div);
> >> }  
> >
> >If the exponent difference between x and y is large enough this
> >returns results which are larger than y. glibc does it completley
> >with integer-operations also.  
> 
> If the values are so large or small that you start to get floating
> point based errors then you should probably be using integer
> arthmetic or a large number library anyway like GMP anyway.
> 

Your method will sometimes produce results that are 1 LSB off
relatively to IEEE-754 prescription when values are neither small nor
large.
And sometimes 1 LSB off means that result is 2x off.
For example, for x=0.9999999999999999, y=0.9999999999999998 your method
produces 2.2204460492503126e-16. A correct result is, of course,
1.1102230246251565e-16

Also, I don't think that your method is any faster than correct methods.

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


#121700

FromMuttley@DastardlyHQ.org
Date2025-02-24 15:10 +0000
Message-ID<vpi25t$1520i$1@dont-email.me>
In reply to#121699
On Mon, 24 Feb 2025 16:22:46 +0200
Michael S <already5chosen@yahoo.com> wibbled:
>On Mon, 24 Feb 2025 13:09:50 -0000 (UTC)
>Muttley@DastardlyHQ.org wrote:
>> If the values are so large or small that you start to get floating
>> point based errors then you should probably be using integer
>> arthmetic or a large number library anyway like GMP anyway.
>> 
>
>Your method will sometimes produce results that are 1 LSB off
>relatively to IEEE-754 prescription when values are neither small nor
>large.
>And sometimes 1 LSB off means that result is 2x off.
>For example, for x=0.9999999999999999, y=0.9999999999999998 your method
>produces 2.2204460492503126e-16. A correct result is, of course,
>1.1102230246251565e-16

Frankly I doubt anyone would care, its zero in all but name.

>Also, I don't think that your method is any faster than correct methods.

Don't know, but its only 3 mathematical operations all of which can be done
by the hardware so its going to be pretty fast.

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


#121703

FromMichael S <already5chosen@yahoo.com>
Date2025-02-24 17:33 +0200
Message-ID<20250224173345.000076a5@yahoo.com>
In reply to#121700
On Mon, 24 Feb 2025 15:10:53 -0000 (UTC)
Muttley@DastardlyHQ.org wrote:

> On Mon, 24 Feb 2025 16:22:46 +0200
> Michael S <already5chosen@yahoo.com> wibbled:
> >On Mon, 24 Feb 2025 13:09:50 -0000 (UTC)
> >Muttley@DastardlyHQ.org wrote:  
> >> If the values are so large or small that you start to get floating
> >> point based errors then you should probably be using integer
> >> arthmetic or a large number library anyway like GMP anyway.
> >>   
> >
> >Your method will sometimes produce results that are 1 LSB off
> >relatively to IEEE-754 prescription when values are neither small nor
> >large.
> >And sometimes 1 LSB off means that result is 2x off.
> >For example, for x=0.9999999999999999, y=0.9999999999999998 your
> >method produces 2.2204460492503126e-16. A correct result is, of
> >course, 1.1102230246251565e-16  
> 
> Frankly I doubt anyone would care, its zero in all but name.
> 
> >Also, I don't think that your method is any faster than correct
> >methods.  
> 
> Don't know, but its only 3 mathematical operations all of which can
> be done by the hardware so its going to be pretty fast.
> 
> 

Looks like 4 operations to me - division, truncation, subtraction,
multiplication. If compiler takes it literally, which he probably
should if compiled without special non-standard-conforming flags like
-fast-math, then there are 5 operations - double->int and
int->double conversions instead of truncation

Nevertheless, after a bit of thinking I concur that your formula is
faster than 100% correct methods. Initially, I didn't took into account
all difficulties that correct methods have to face in cases of very
large x to y ratios.

However your method is approximately the same speed as *mostly correct*
method shown in my post above. May be, yours is even a little slower,
at least as long as we use good optimizing compiler and target modern
CPUs that support trunc() and fma() as fast hardware instructions.


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


#121705

FromMuttley@DastardlyHQ.org
Date2025-02-24 16:48 +0000
Message-ID<vpi7sa$185h2$1@dont-email.me>
In reply to#121703
On Mon, 24 Feb 2025 17:33:45 +0200
Michael S <already5chosen@yahoo.com> wibbled:
>On Mon, 24 Feb 2025 15:10:53 -0000 (UTC)
>Muttley@DastardlyHQ.org wrote:
>> Don't know, but its only 3 mathematical operations all of which can
>> be done by the hardware so its going to be pretty fast.
>> 
>> 
>
>Looks like 4 operations to me - division, truncation, subtraction,
>multiplication. If compiler takes it literally, which he probably

Yes, I should have included the cast. Not sure whether that could be done
in hardware or not, my assembler knowledge - for x86 - is way too rusty.

>Nevertheless, after a bit of thinking I concur that your formula is
>faster than 100% correct methods. Initially, I didn't took into account
>all difficulties that correct methods have to face in cases of very
>large x to y ratios.

In those sorts of cases the result of your program will be running into 
floating point precision errors elsewhere so IMO its somewhat moot. 

>However your method is approximately the same speed as *mostly correct*
>method shown in my post above. May be, yours is even a little slower,
>at least as long as we use good optimizing compiler and target modern
>CPUs that support trunc() and fma() as fast hardware instructions.

The only way to really know would be to test it on various OS's and CPUs 
I guess.

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


#121706

FromMr Flibble <leigh@i42.co.uk>
Date2025-02-24 22:21 +0000
Message-ID<25sprjpqelnhcj7phqo1b0av7ht1espdui@4ax.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.

double myFmod(double x, double y)
{
        double div = x / y;
        return y * (div - std::round(div));
}

/Flibble

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


#121707

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-02-25 07:37 +0100
Message-ID<vpjof3$1pr7l$1@raubtier-asyl.eternal-september.org>
In reply to#121706
Am 24.02.2025 um 23:21 schrieb Mr Flibble:

> double myFmod(double x, double y)
> {
>          double div = x / y;
>          return y * (div - std::round(div));
> }

Doesn't work, not only for the reasons already mentioned.

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


#121717

FromMr Flibble <leigh@i42.co.uk>
Date2025-02-25 23:03 +0000
Message-ID<dsisrjp5acgperofudgriamakq7gl71jgp@4ax.com>
In reply to#121707
On Tue, 25 Feb 2025 07:37:23 +0100, Bonita Montero
<Bonita.Montero@gmail.com> wrote:

>Am 24.02.2025 um 23:21 schrieb Mr Flibble:
>
>> double myFmod(double x, double y)
>> {
>>          double div = x / y;
>>          return y * (div - std::round(div));
>> }
>
>Doesn't work, not only for the reasons already mentioned.

double myFmod(double x, double y)
{
         double div = x / y;
         return y * (div - std::trunc(div));
}

/Flibble

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


#121718

FromMichael S <already5chosen@yahoo.com>
Date2025-02-26 02:00 +0200
Message-ID<20250226020048.00007b10@yahoo.com>
In reply to#121717
On Tue, 25 Feb 2025 23:03:04 +0000
Mr Flibble <leigh@i42.co.uk> wrote:

> On Tue, 25 Feb 2025 07:37:23 +0100, Bonita Montero
> <Bonita.Montero@gmail.com> wrote:
> 
> >Am 24.02.2025 um 23:21 schrieb Mr Flibble:
> >  
> >> double myFmod(double x, double y)
> >> {
> >>          double div = x / y;
> >>          return y * (div - std::round(div));
> >> }  
> >
> >Doesn't work, not only for the reasons already mentioned.  
> 
> double myFmod(double x, double y)
> {
>          double div = x / y;
>          return y * (div - std::trunc(div));
> }
> 
> /Flibble


Even ignoring potential overflow during division, this method is
very imprecise.
(1e3/9 - trunc(1e3/9))*9 = 1.000000000000028
(1e6/9 - trunc(1e6/9))*9 = 0.999999999985448
(1e9/9 - trunc(1e9/9))*9 = 0.999999940395355
(1e12/9 - trunc(1e12/9))*9 = 1.000030517578125
(1e15/9 - trunc(1e15/9))*9 = 0.984375

OTOH
1e3/9 - trunc(1e3/9)*9 = 1
1e6/9 - trunc(1e6/9)*9 = 1
1e9/9 - trunc(1e9/9)*9 = 1
1e12/9 - trunc(1e12/9)*9 = 1
1e15/9 - trunc(1e15/9)*9 = 1

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


#121719

FromWuns Haerst <Wuns.Haerst@wurstfabrik.at>
Date2025-02-26 04:01 +0100
Message-ID<vpm05h$29f2i$1@raubtier-asyl.eternal-september.org>
In reply to#121717
Am 26.02.2025 um 00:03 schrieb Mr Flibble:

> double myFmod(double x, double y)
> {
>           double div = x / y;
>           return y * (div - std::trunc(div));
> }

Produces a lot of erroneous results.

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


#121709

FromMuttley@DastardlyHQ.org
Date2025-02-25 08:24 +0000
Message-ID<vpjuoo$1rfgd$1@dont-email.me>
In reply to#121706
On Mon, 24 Feb 2025 22:21:03 +0000
Mr Flibble <leigh@i42.co.uk> wibbled:
>On Mon, 24 Feb 2025 11:48:08 +0100, Bonita Montero
><Bonita.Montero@gmail.com> wrote:
>>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.
>
>double myFmod(double x, double y)
>{
>        double div = x / y;
>        return y * (div - std::round(div));
>}

You don't ever want it rounded up, it must always just be the integer component.

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


#121724

FromMr Flibble <leigh@i42.co.uk>
Date2025-02-27 21:16 +0000
Message-ID<vbl1sjpti6kqe8utdk6bt0718lfh95gfkc@4ax.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.

double myFmod(double x, double y)
{
    return x / y - std::trunc(x / y) * y;
}

/Flibble

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


#121725

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-02-28 07:59 +0100
Message-ID<vprmsh$3ia4v$1@raubtier-asyl.eternal-september.org>
In reply to#121724
Am 27.02.2025 um 22:16 schrieb Mr Flibble:

> double myFmod(double x, double y)
> {
>      return x / y - std::trunc(x / y) * y;
> }

In most cases ths has a precision-loss which can lead to a result
which is larger than y. Current solutions are similar to my code
and are always 100% exact.

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


#121728

FromMichael S <already5chosen@yahoo.com>
Date2025-02-28 12:35 +0200
Message-ID<20250228123529.000002e9@yahoo.com>
In reply to#121724
On Thu, 27 Feb 2025 21:16:50 +0000
Mr Flibble <leigh@i42.co.uk> wrote:

> 
> double myFmod(double x, double y)
> {
>     return x / y - std::trunc(x / y) * y;
> }
> 
> /Flibble

Nonsense. 

The one below is not nonsense, but still very bad.
double myFmod(double x, double y)
{
  return x - trunc(x / y) * y;
}

All solutions that work for all combinations of inputs are complicated.
They can be based either on integer arithmetic or on FMA. 

In the former case in order to get any sort of speed one has to use
non-standard extensions to the language, like gcc __int128 or MS/Intel
_umul128/_umulh or MS/ARM __umulh.

In the latter class of solutions one has to be careful about rounding -
either check on every step that rounding didn't went a wrong way or set
rounding mode to FE_TOWARDZERO at the beginning and restore it to
original at the end.

For both solutions worst case (huge x, tiny y) is pretty slow - 30-40
steps with several arithmetic operations on every step. Without
experimentation it is hard to say which of the solutions is faster. It
depends on your hardware, anyway.


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


#121730

FromMr Flibble <leigh@i42.co.uk>
Date2025-02-28 18:12 +0000
Message-ID<8uu3sjpvfpivg04ce2vplkr3kb2ma8juq6@4ax.com>
In reply to#121728
On Fri, 28 Feb 2025 12:35:29 +0200, Michael S
<already5chosen@yahoo.com> wrote:

>On Thu, 27 Feb 2025 21:16:50 +0000
>Mr Flibble <leigh@i42.co.uk> wrote:
>
>> 
>> double myFmod(double x, double y)
>> {
>>     return x / y - std::trunc(x / y) * y;
>> }
>> 
>> /Flibble
>
>Nonsense. 
>
>The one below is not nonsense, but still very bad.
>double myFmod(double x, double y)
>{
>  return x - trunc(x / y) * y;
>}

Yes it is nonsense, YOUR nonsense (I didn't actually think about the
problem, just reposted yours as I foolishly assumed you were correct):

On Wed, 26 Feb 2025 02:00:48 +0200, Michael S
<already5chosen@yahoo.com> wrote:

>Even ignoring potential overflow during division, this method is
>very imprecise.
>(1e3/9 - trunc(1e3/9))*9 = 1.000000000000028
>(1e6/9 - trunc(1e6/9))*9 = 0.999999999985448
>(1e9/9 - trunc(1e9/9))*9 = 0.999999940395355
>(1e12/9 - trunc(1e12/9))*9 = 1.000030517578125
>(1e15/9 - trunc(1e15/9))*9 = 0.984375
>
>OTOH
>1e3/9 - trunc(1e3/9)*9 = 1
>1e6/9 - trunc(1e6/9)*9 = 1
>1e9/9 - trunc(1e9/9)*9 = 1
>1e12/9 - trunc(1e12/9)*9 = 1
>1e15/9 - trunc(1e15/9)*9 = 1
>

/Flibble

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


#121731

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-02-28 19:23 +0100
Message-ID<vpsuvj$3pgn4$1@raubtier-asyl.eternal-september.org>
In reply to#121724
Am 27.02.2025 um 22:16 schrieb Mr Flibble:

> double myFmod(double x, double y)
> {
>      return x / y - std::trunc(x / y) * y;
> }

I weote a little test to find out how often the result is imprecise and
how often it is out of range:

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

using namespace std;

double trivialFmod( double a, double b );

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 = trivialFmod( 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 trivialFmod( double a, double b )
{
	return a - trunc( a / b ) * b;
}

The output is:

imprecise: 49.9096%
out of range: 2.0039%

I'd never expected that half of the results are precise and that
only two percent of the results are out of range. But that's still
unusable.

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


#121732

FromMr Flibble <leigh@i42.co.uk>
Date2025-02-28 18:30 +0000
Message-ID<sov3sjdkgr1ok5nbnd167ldqdlhitvrbh8@4ax.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.

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

/Flibble

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


#121733

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-02-28 19:31 +0100
Message-ID<vpsvee$3pkf7$1@raubtier-asyl.eternal-september.org>
In reply to#121732
Am 28.02.2025 um 19:30 schrieb Mr Flibble:

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

This still sucks. Try it with this test:

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

using namespace std;

double trivialFmod( double a, double b );

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 = trivialFmod( 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 trivialFmod( double a, double b )
{
     return a - trunc( a / b ) * b;
}

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


#121734

FromMr Flibble <leigh@i42.co.uk>
Date2025-02-28 19:47 +0000
Message-ID<hk44sj96knc6j4pr45g0e7m1e8ck1innqb@4ax.com>
In reply to#121733
On Fri, 28 Feb 2025 19:31:44 +0100, Bonita Montero
<Bonita.Montero@gmail.com> wrote:

>Am 28.02.2025 um 19:30 schrieb Mr Flibble:
>
>> double my_fmod(double x, double y)
>> {
>>      if (y == 0.0)
>> 	return x / y;
>>      return x - std::trunc(x / y) * y;
>> }
>
>This still sucks. Try it with this test:
>
>#include <iostream>
>#include <cmath>
>#include <random>
>#include <bit>
>
>using namespace std;
>
>double trivialFmod( double a, double b );
>
>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 = trivialFmod( 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 trivialFmod( double a, double b )
>{
>     return a - trunc( a / b ) * b;
>}
>

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

/Flibble

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


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

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


csiph-web