Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #121694 > unrolled thread
| Started by | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| First post | 2025-02-24 11:48 +0100 |
| Last post | 2025-03-09 14:56 +0200 |
| Articles | 20 on this page of 134 — 8 participants |
Back to article view | Back to comp.lang.c++
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 →
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-02-28 16:28 +0200 |
| Subject | FP_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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2025-03-01 08:35 -0800 |
| Subject | Re: 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]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-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]
| From | Muttley@DastardlyHQ.org |
|---|---|
| Date | 2025-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]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-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]
| From | Muttley@DastardlyHQ.org |
|---|---|
| Date | 2025-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]
| From | Mr Flibble <leigh@i42.co.uk> |
|---|---|
| Date | 2025-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-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]
| From | Mr Flibble <leigh@i42.co.uk> |
|---|---|
| Date | 2025-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]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-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]
| From | Wuns Haerst <Wuns.Haerst@wurstfabrik.at> |
|---|---|
| Date | 2025-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]
| From | Muttley@DastardlyHQ.org |
|---|---|
| Date | 2025-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]
| From | Mr Flibble <leigh@i42.co.uk> |
|---|---|
| Date | 2025-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-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]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-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]
| From | Mr Flibble <leigh@i42.co.uk> |
|---|---|
| Date | 2025-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-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]
| From | Mr Flibble <leigh@i42.co.uk> |
|---|---|
| Date | 2025-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2025-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]
| From | Mr Flibble <leigh@i42.co.uk> |
|---|---|
| Date | 2025-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