zarr-python icon indicating copy to clipboard operation
zarr-python copied to clipboard

Negative zero not preserved

Open tomwhite opened this issue 6 months ago • 5 comments

Zarr version

v3.0.8

Numcodecs version

v0.15.1

Python Version

3.11

Operating System

Mac

Installation

pip in a venv

Description

Negative zero (-0.0) is not distinguished from zero when reading back values from a Zarr array. This differs from the expected behaviour (and Zarr Python v2).

Steps to reproduce

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "zarr@git+https://github.com/zarr-developers/zarr-python.git@main",
# ]
# ///
#
# This script automatically imports the development branch of zarr to check for issues

import numpy as np
import zarr
print(zarr.array(np.array([0.0, -0.0]))[:])
#zarr.print_debug_info()

This prints

[0. 0.]

But with Zarr 2.18.7 it correctly prints

[ 0. -0.]

Additional output

No response

tomwhite avatar Jun 18 '25 09:06 tomwhite

thanks for this report, I did a quick check and this bug was present prior to the recent dtype changes, so that should help narrow the search down a bit.

d-v-b avatar Jun 18 '25 09:06 d-v-b

thanks for this report, I did a quick check and this bug was present prior to the recent dtype changes, so that should help narrow the search down a bit.

Yes, sorry I forgot to say it is in 3.0.8 as well as main.

tomwhite avatar Jun 18 '25 09:06 tomwhite

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "zarr==3.0.8",
# ]
# ///
#
# This script automatically imports the development branch of zarr to check for issues

import numpy as np
import zarr
print(zarr.array(np.array([0.0, -0.0]), fill_value=1)[:])

Adding a non-0 fill value preserves the signed 0 as expected. I also checked that the original test case doesn't write any chunks. So the error comes from zarr mistakenly identifying the chunk as empty during array creation, thenfailing to write it, which results in zarr using the fill value instead on indexing.

d-v-b avatar Jun 18 '25 09:06 d-v-b

Aha - which explains why it works on v2 - the default for write_empty_chunks is True (it's False in v3). On v2 the following fails too:

>>> print(zarr.array(np.array([0.0, -0.0]), write_empty_chunks=False)[:])
[0. 0.]

tomwhite avatar Jun 18 '25 10:06 tomwhite

I suspect we are relying on this behavior:

>>> np.array([0.0]) == np.array([-0.0])
array([ True])

We probably need to define a stricter type of equality.

d-v-b avatar Jun 18 '25 10:06 d-v-b