Skip to content

Feature: Add a truncation mode to nk.astype for float-to-integer casts #377

Description

@ternaus

Request

Add an explicit truncate-toward-zero mode for float-to-integer conversions in nk.astype.

Why

nk.astype currently rounds float inputs to the nearest even integer and saturates overflow. That is useful for image operations that need rounded pixels. Other image pipelines already clip values to the destination range and then rely on NumPy astype to discard the fractional part. Those paths need 1.9 -> 1, while the current NumKong conversion produces 1.9 -> 2.

This matters independently of the buffer-first API from #368: the current conversion cannot replace a NumPy cast when truncation is part of the result contract.

Proposed API

result = nk.astype(values, "uint8", rounding="truncate")
nk.astype(values, "uint8", rounding="truncate", out=output)

rounding="nearest_even" can remain the default, preserving the current behavior. The exact parameter name is flexible; the important part is an explicit, documented truncation mode.

Contract

For float-to-integer conversions with truncation enabled:

  • discard the fractional part toward zero: -1.9 -> -1, -0.5 -> 0, 0.5 -> 0, 1.9 -> 1;
  • saturate values outside the destination integer range after truncation;
  • preserve the existing NaN and infinity rules;
  • retain the existing shape, arbitrary-rank input, strided-input, and out= contracts from Feature: Buffer-first N-D cast with out= and explicit conversion semantics #368;
  • reject or document the mode for conversions that are not float-to-integer.

For the common clipped uint8 route, the intended behavior is:

values = np.clip(values, 0, 255)
expected = values.astype(np.uint8)
actual = nk.astype(values, "uint8", rounding="truncate")
np.testing.assert_array_equal(actual, expected)

Tests

Cover positive and negative fractional values, half-integers, integer boundaries, clipped and unclipped overflow, NaN, infinities, contiguous and strided inputs, and caller-owned out buffers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions