Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

double.IsPow2 reports incorrectly for subnormal numbers #88023

Closed
hamarb123 opened this issue Jun 25, 2023 · 2 comments · Fixed by #88839
Closed

double.IsPow2 reports incorrectly for subnormal numbers #88023

hamarb123 opened this issue Jun 25, 2023 · 2 comments · Fixed by #88839

Comments

@hamarb123
Copy link
Contributor

Description

double.IsPow2 should return true for for all doubles which are a power of 2, and false otherwise. It doesn't appear to work correctly for subnormal numbers.

Reproduction Steps

Execute the following:

double.IsPow2(double.Epsilon * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 16); //not subnormal, = 2^-1022
double.IsPow2(double.Epsilon * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 8); //is subnormal, = 2^-1023
double.IsPow2(double.Epsilon); //is subnormal, = 2^-1074

Expected behavior

double.IsPow2(double.Epsilon * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 16); //true
double.IsPow2(double.Epsilon * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 8); //true
double.IsPow2(double.Epsilon); //true

Actual behavior

double.IsPow2(double.Epsilon * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 16); //true
double.IsPow2(double.Epsilon * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 8); //false
double.IsPow2(double.Epsilon); //false

Regression?

No response

Known Workarounds

No response

Configuration

Reproduces on:
.NET 8.0.0-preview.5.23280.8, 7.0.5.
Windows 10 Pro 10.0.19045.3086 x64
No, it probably isn't specific to this configuration.

Other information

The simplest correct check I can think of for this would be: check the negative bit is not set, check the exponent is not the max exponent (can be combined with previous check), if the exponent is not zero: check the mantissa is 0, if the exponent is zero: check the PopCount is 1.

It seems to also reproduce with float and Half, I only checked T.IsPow2(T.Epsilon), but these should both return true also.

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Jun 25, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Jun 25, 2023
@ghost
Copy link

ghost commented Jun 25, 2023

Tagging subscribers to this area: @dotnet/area-system-numerics
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

double.IsPow2 should return true for for all doubles which are a power of 2, and false otherwise. It doesn't appear to work correctly for subnormal numbers.

Reproduction Steps

Execute the following:

double.IsPow2(double.Epsilon * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 16); //not subnormal, = 2^-1022
double.IsPow2(double.Epsilon * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 8); //is subnormal, = 2^-1023
double.IsPow2(double.Epsilon); //is subnormal, = 2^-1074

Expected behavior

double.IsPow2(double.Epsilon * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 16); //true
double.IsPow2(double.Epsilon * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 8); //true
double.IsPow2(double.Epsilon); //true

Actual behavior

double.IsPow2(double.Epsilon * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 16); //true
double.IsPow2(double.Epsilon * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 64 * 8); //false
double.IsPow2(double.Epsilon); //false

Regression?

No response

Known Workarounds

No response

Configuration

Reproduces on:
.NET 8.0.0-preview.5.23280.8, 7.0.5.
Windows 10 Pro 10.0.19045.3086 x64
No, it probably isn't specific to this configuration.

Other information

The simplest correct check I can think of for this would be: check the negative bit is not set, check the exponent is not the max exponent (can be combined with previous check), if the exponent is not zero: check the mantissa is 0, if the exponent is zero: check the PopCount is 1.

It seems to also reproduce with float and Half, I only checked T.IsPow2(T.Epsilon), but these should both return true also.

Author: hamarb123
Assignees: -
Labels:

area-System.Numerics, untriaged, needs-area-label

Milestone: -

@jkotas jkotas removed the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Jun 25, 2023
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 13, 2023
@ghost ghost removed in-pr There is an active PR which will close this issue when it is merged untriaged New issue has not been triaged by the area owner labels Jul 14, 2023
@danmoseley
Copy link
Member

Good catch @hamarb123

@ghost ghost locked as resolved and limited conversation to collaborators Aug 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
3 participants