Skip to content

Improve Python interoperability of System.Half - #2153

Merged
BCSharp merged 7 commits into
IronLanguages:mainfrom
BCSharp:half-constr
Nov 7, 2026
Merged

BCSharp merged 7 commits into
IronLanguages:mainfrom
BCSharp:half-constr

Conversation

@BCSharp

@BCSharp BCSharp commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

System.Half had no Python-level support beyond what .NET exposes on its own: instances could only be created with clr.Convert, and several common Python operations silently produced wrong results. This PR started with adding a proper constructor to Half: in C#, it's easy to write (Half)0.5, but in IronPython, one needed the verbose clr.Convert(0.5, Half). There is no 16-bit sized float in CPython, but Half is basically the same as NumPy.float16, so I took that as the guide to add more functionality to Half.

The goal is to make Half behave correctly as a Python object, not to turn it into a Python float or even System.Single. Mixed-type arithmetic and comparisons (Half(1) + 1, Half(1) < 2.0) stay unsupported, as they are in C#, which has no implicit conversions between Half and other numeric types (though surprisingly, Byte gets automatically widened to Half in C#; not in IronPython). Same-type operators on Half are supported by the generic math in .NET.

Changes

Before After
Constructor System.Half(1.5) → TypeError: CreateInstance() takes no arguments Accepts the same arguments as System.Single(...): numbers, strings, objects with __float__
copy / pickle Silently reconstructed Half(0) Round-trips (via __getnewargs__, as for Single)
format(clr.Convert(1.5, Half), '.2f') '22f' (spec passed to Half.ToString as a .NET custom format) '1.50': formatted like a float with the same exact value; format(h, '') equals str(h)
str / repr <System.Half object at 0x… [0.1]>; str was culture-dependent and lossy (65500 (as MaxValue), NaN, ∞) Shortest round-trip string, culture-independent (6.55e+04 nan, inf)
Math.Abs(clr.Convert(1.5, Half)) 1 (bound to Abs(Int32) via __int__); inf → 2147483647, nan → 0 1.5 (binds to the lossless Abs(Double))
real, imag, conjugate() AttributeError Implemented as for Single, typed as Half

@slozier slozier left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Just the small suggestion about __bool__ (unless it was intentionally omitted).

public static Half Getimag(Half self) => default;

public static Half conjugate(Half self) => self;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public static bool __bool__(Half self) => !self.IsZero;

might be worth it...

@BCSharp
BCSharp merged commit feb5e15 into IronLanguages:main Nov 7, 2026
35 checks passed
@BCSharp
BCSharp deleted the half-constr branch November 7, 2026 04:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants