How does the argument omit-unity-mantissa works in zero?

Please consider the following minimal working example:

#import "@preview/zero:0.6.1": num, set-num

#set-num(
    exponent: "sci",
    math: true, 
    product: math.dot,
    tight: true,
    omit-unity-mantissa: true
  )

#num(100)  /// ==> 1.00 dot 10^2  --> expected: 10^2

#num(1e4)  /// ===> 1.0000 dot 10^4 --> expected: 10^4

Observing how the #num() function us used and described in zero – Typst Universe leads to:

  • number: str | content | int | float | array : Number input; str is preferred. If the input is content, it may only contain text nodes. Numeric types int and float are supported but not encouraged because of information loss (e.g., the number of trailing “0” digits or the exponent).

This is in line with the examples provided:

It is recommended to use #num("value") or #num[value].

Now, you will notice it does work for a value of 1e4, but not for 100. This probably has to do with the fact that 100 is not scientific format and the mantissa is 100 and not 1.

We’d have to check the code or ask @Mc-Zen.

Works when the mantissa is 1 (and not something else, as designed it seems).

  • omit-unity-mantissa: bool = false : Determines whether a mantissa of 1 is omitted in scientific notation, e.g., 10⁴ instead of 1·10⁴.
// This one should not work as the mantissa is not 1
#let val = (mantissa: 1000, e: 1, pm: none)
#num(val)

#let val = (mantissa: 1, e: 4, pm: none)
#num(val)

#num("1e4")

#num[1e4]

Hi, author of Zero here.

This is an excellent question.

The rule for omit-unity-mantissa works itself is simple: when the mantissa is exactly 1 (and not 1.0 or similar) and the exponent is present, the mantissa is omitted.

We could in principle overthink this behavior but one needs to be very careful since 1 and 1.0 are two quite different things as they differ in the precision that they specify. When we measure, say, a length and name the result to be 1.00m, that means “one meter up to centimeter precision”.

This is also the difference in how num[100] and num[1e2] are treated: for scientific and engineering notation, the input precision is preserved. In the case of num[100] we have a precision of 3 significant figures which is then turned to 1.00×10². On the other hand, in num[1e2] there is only one significant figure specified. With float input, the situation is ambiguous since num(100.) and num(1e2) are exactly identical and indistinguishable.

I recommend reading the discussion in big `float` trailing zeros in `sci`/`eng` mode · Issue #66 · Mc-Zen/zero · GitHub for more information on this topic.

The next version of Zero will feature a new option trim-zeros that can be used to discard any trailing zeros (and thus also the potential precision information that they carry).

For the case of omit-unity-mantissa, I’m unsure whether it could make sense to have an exception and also omit mantissae like 1.00. This would need some thinking.