Skip to content

Commit

Permalink
[move stdlib] Add fun bitwise_not and macro fun max_value (Mysten…
Browse files Browse the repository at this point in the history
…Labs#19126)

## Description 

- Added a bitwise not function, `fun bitwise_not` to `u*` modules
- Added a maximum value macro, `macro fun max_value` to `u*` modules

## Test plan 

- New tests 

---

## Release notes

Check each box that your changes affect. If none of the boxes relate to
your changes, release notes aren't required.

For each box you select, include information after the relevant heading
that describes the impact of your changes that a user might notice and
any actions they must take to implement updates.

- [ ] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [ ] Indexer: 
- [ ] JSON-RPC: 
- [ ] GraphQL: 
- [X] CLI: Move integer modules now have a `bitwise_not` function and a
`max_value` macro function.
- [ ] Rust SDK:
- [ ] REST API:
  • Loading branch information
tnowacki authored Sep 5, 2024
1 parent 7d0ebb9 commit 369d44b
Show file tree
Hide file tree
Showing 19 changed files with 662 additions and 17 deletions.
134 changes: 133 additions & 1 deletion crates/sui-framework/docs/move-stdlib/u128.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,53 @@ title: Module `0x1::u128`



- [Function `bitwise_not`](#0x1_u128_bitwise_not)
- [Function `max`](#0x1_u128_max)
- [Function `min`](#0x1_u128_min)
- [Function `diff`](#0x1_u128_diff)
- [Function `divide_and_round_up`](#0x1_u128_divide_and_round_up)
- [Function `pow`](#0x1_u128_pow)
- [Function `sqrt`](#0x1_u128_sqrt)
- [Function `try_as_u8`](#0x1_u128_try_as_u8)
- [Function `try_as_u16`](#0x1_u128_try_as_u16)
- [Function `try_as_u32`](#0x1_u128_try_as_u32)
- [Function `try_as_u64`](#0x1_u128_try_as_u64)
- [Function `to_string`](#0x1_u128_to_string)


<pre><code><b>use</b> <a href="../move-stdlib/string.md#0x1_string">0x1::string</a>;
<pre><code><b>use</b> <a href="../move-stdlib/option.md#0x1_option">0x1::option</a>;
<b>use</b> <a href="../move-stdlib/string.md#0x1_string">0x1::string</a>;
<b>use</b> <a href="../move-stdlib/vector.md#0x1_vector">0x1::vector</a>;
</code></pre>



<a name="0x1_u128_bitwise_not"></a>

## Function `bitwise_not`

Returns the bitwise not of the value.
Each bit that is 1 becomes 0. Each bit that is 0 becomes 1.


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u128.md#0x1_u128_bitwise_not">bitwise_not</a>(x: <a href="../move-stdlib/u128.md#0x1_u128">u128</a>): <a href="../move-stdlib/u128.md#0x1_u128">u128</a>
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u128.md#0x1_u128_bitwise_not">bitwise_not</a>(x: <a href="../move-stdlib/u128.md#0x1_u128">u128</a>): <a href="../move-stdlib/u128.md#0x1_u128">u128</a> {
x ^ max_value!()
}
</code></pre>



</details>

<a name="0x1_u128_max"></a>

## Function `max`
Expand Down Expand Up @@ -191,6 +223,106 @@ math::sqrt(8 * 1000000) => 2828; // same as above, 2828 / 1000 (2.828)



</details>

<a name="0x1_u128_try_as_u8"></a>

## Function `try_as_u8`

Try to convert a <code><a href="../move-stdlib/u128.md#0x1_u128">u128</a></code> to a <code>u8</code>. Returns <code>None</code> if the value is too large.


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u128.md#0x1_u128_try_as_u8">try_as_u8</a>(x: <a href="../move-stdlib/u128.md#0x1_u128">u128</a>): <a href="../move-stdlib/option.md#0x1_option_Option">option::Option</a>&lt;u8&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u128.md#0x1_u128_try_as_u8">try_as_u8</a>(x: <a href="../move-stdlib/u128.md#0x1_u128">u128</a>): Option&lt;u8&gt; {
std::macros::try_as_u8!(x)
}
</code></pre>



</details>

<a name="0x1_u128_try_as_u16"></a>

## Function `try_as_u16`

Try to convert a <code><a href="../move-stdlib/u128.md#0x1_u128">u128</a></code> to a <code>u16</code>. Returns <code>None</code> if the value is too large.


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u128.md#0x1_u128_try_as_u16">try_as_u16</a>(x: <a href="../move-stdlib/u128.md#0x1_u128">u128</a>): <a href="../move-stdlib/option.md#0x1_option_Option">option::Option</a>&lt;u16&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u128.md#0x1_u128_try_as_u16">try_as_u16</a>(x: <a href="../move-stdlib/u128.md#0x1_u128">u128</a>): Option&lt;u16&gt; {
std::macros::try_as_u16!(x)
}
</code></pre>



</details>

<a name="0x1_u128_try_as_u32"></a>

## Function `try_as_u32`

Try to convert a <code><a href="../move-stdlib/u128.md#0x1_u128">u128</a></code> to a <code>u32</code>. Returns <code>None</code> if the value is too large.


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u128.md#0x1_u128_try_as_u32">try_as_u32</a>(x: <a href="../move-stdlib/u128.md#0x1_u128">u128</a>): <a href="../move-stdlib/option.md#0x1_option_Option">option::Option</a>&lt;u32&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u128.md#0x1_u128_try_as_u32">try_as_u32</a>(x: <a href="../move-stdlib/u128.md#0x1_u128">u128</a>): Option&lt;u32&gt; {
std::macros::try_as_u32!(x)
}
</code></pre>



</details>

<a name="0x1_u128_try_as_u64"></a>

## Function `try_as_u64`

Try to convert a <code><a href="../move-stdlib/u128.md#0x1_u128">u128</a></code> to a <code><a href="../move-stdlib/u64.md#0x1_u64">u64</a></code>. Returns <code>None</code> if the value is too large.


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u128.md#0x1_u128_try_as_u64">try_as_u64</a>(x: <a href="../move-stdlib/u128.md#0x1_u128">u128</a>): <a href="../move-stdlib/option.md#0x1_option_Option">option::Option</a>&lt;<a href="../move-stdlib/u64.md#0x1_u64">u64</a>&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u128.md#0x1_u128_try_as_u64">try_as_u64</a>(x: <a href="../move-stdlib/u128.md#0x1_u128">u128</a>): Option&lt;<a href="../move-stdlib/u64.md#0x1_u64">u64</a>&gt; {
std::macros::try_as_u64!(x)
}
</code></pre>



</details>

<a name="0x1_u128_to_string"></a>
Expand Down
108 changes: 107 additions & 1 deletion crates/sui-framework/docs/move-stdlib/u64.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,52 @@ title: Module `0x1::u64`



- [Function `bitwise_not`](#0x1_u64_bitwise_not)
- [Function `max`](#0x1_u64_max)
- [Function `min`](#0x1_u64_min)
- [Function `diff`](#0x1_u64_diff)
- [Function `divide_and_round_up`](#0x1_u64_divide_and_round_up)
- [Function `pow`](#0x1_u64_pow)
- [Function `sqrt`](#0x1_u64_sqrt)
- [Function `try_as_u8`](#0x1_u64_try_as_u8)
- [Function `try_as_u16`](#0x1_u64_try_as_u16)
- [Function `try_as_u32`](#0x1_u64_try_as_u32)
- [Function `to_string`](#0x1_u64_to_string)


<pre><code><b>use</b> <a href="../move-stdlib/string.md#0x1_string">0x1::string</a>;
<pre><code><b>use</b> <a href="../move-stdlib/option.md#0x1_option">0x1::option</a>;
<b>use</b> <a href="../move-stdlib/string.md#0x1_string">0x1::string</a>;
<b>use</b> <a href="../move-stdlib/vector.md#0x1_vector">0x1::vector</a>;
</code></pre>



<a name="0x1_u64_bitwise_not"></a>

## Function `bitwise_not`

Returns the bitwise not of the value.
Each bit that is 1 becomes 0. Each bit that is 0 becomes 1.


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u64.md#0x1_u64_bitwise_not">bitwise_not</a>(x: <a href="../move-stdlib/u64.md#0x1_u64">u64</a>): <a href="../move-stdlib/u64.md#0x1_u64">u64</a>
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u64.md#0x1_u64_bitwise_not">bitwise_not</a>(x: <a href="../move-stdlib/u64.md#0x1_u64">u64</a>): <a href="../move-stdlib/u64.md#0x1_u64">u64</a> {
x ^ max_value!()
}
</code></pre>



</details>

<a name="0x1_u64_max"></a>

## Function `max`
Expand Down Expand Up @@ -191,6 +222,81 @@ math::sqrt(8 * 1000000) => 2828; // same as above, 2828 / 1000 (2.828)



</details>

<a name="0x1_u64_try_as_u8"></a>

## Function `try_as_u8`

Try to convert a <code><a href="../move-stdlib/u64.md#0x1_u64">u64</a></code> to a <code>u8</code>. Returns <code>None</code> if the value is too large.


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u64.md#0x1_u64_try_as_u8">try_as_u8</a>(x: <a href="../move-stdlib/u64.md#0x1_u64">u64</a>): <a href="../move-stdlib/option.md#0x1_option_Option">option::Option</a>&lt;u8&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u64.md#0x1_u64_try_as_u8">try_as_u8</a>(x: <a href="../move-stdlib/u64.md#0x1_u64">u64</a>): Option&lt;u8&gt; {
std::macros::try_as_u8!(x)
}
</code></pre>



</details>

<a name="0x1_u64_try_as_u16"></a>

## Function `try_as_u16`

Try to convert a <code><a href="../move-stdlib/u64.md#0x1_u64">u64</a></code> to a <code>u16</code>. Returns <code>None</code> if the value is too large.


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u64.md#0x1_u64_try_as_u16">try_as_u16</a>(x: <a href="../move-stdlib/u64.md#0x1_u64">u64</a>): <a href="../move-stdlib/option.md#0x1_option_Option">option::Option</a>&lt;u16&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u64.md#0x1_u64_try_as_u16">try_as_u16</a>(x: <a href="../move-stdlib/u64.md#0x1_u64">u64</a>): Option&lt;u16&gt; {
std::macros::try_as_u16!(x)
}
</code></pre>



</details>

<a name="0x1_u64_try_as_u32"></a>

## Function `try_as_u32`

Try to convert a <code><a href="../move-stdlib/u64.md#0x1_u64">u64</a></code> to a <code>u32</code>. Returns <code>None</code> if the value is too large.


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u64.md#0x1_u64_try_as_u32">try_as_u32</a>(x: <a href="../move-stdlib/u64.md#0x1_u64">u64</a>): <a href="../move-stdlib/option.md#0x1_option_Option">option::Option</a>&lt;u32&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../move-stdlib/u64.md#0x1_u64_try_as_u32">try_as_u32</a>(x: <a href="../move-stdlib/u64.md#0x1_u64">u64</a>): Option&lt;u32&gt; {
std::macros::try_as_u32!(x)
}
</code></pre>



</details>

<a name="0x1_u64_to_string"></a>
Expand Down
31 changes: 31 additions & 0 deletions crates/sui-framework/packages/move-stdlib/sources/macros.move
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,35 @@ module std::macros {
public macro fun do_eq($stop: _, $f: |_|) {
range_do_eq!(0, $stop, $f)
}

public macro fun try_as_u8($x: _): Option<u8> {
let x = $x;
if (x > 0xFF) option::none()
else option::some(x as u8)
}

public macro fun try_as_u16($x: _): Option<u16> {
let x = $x;
if (x > 0xFFFF) option::none()
else option::some(x as u16)
}

public macro fun try_as_u32($x: _): Option<u32> {
let x = $x;
if (x > 0xFFFF_FFFF) option::none()
else option::some(x as u32)
}

public macro fun try_as_u64($x: _): Option<u64> {
let x = $x;
if (x > 0xFFFF_FFFF_FFFF_FFFF) option::none()
else option::some(x as u64)
}

public macro fun try_as_u128($x: _): Option<u128> {
let x = $x;
if (x > 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF) option::none()
else option::some(x as u128)
}

}
31 changes: 31 additions & 0 deletions crates/sui-framework/packages/move-stdlib/sources/u128.move
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
module std::u128 {
use std::string::String;

/// Returns the bitwise not of the value.
/// Each bit that is 1 becomes 0. Each bit that is 0 becomes 1.
public fun bitwise_not(x: u128): u128 {
x ^ max_value!()
}

/// Return the larger of `x` and `y`
public fun max(x: u128, y: u128): u128 {
std::macros::num_max!(x, y)
Expand Down Expand Up @@ -59,10 +65,35 @@ module std::u128 {
std::macros::num_sqrt!<u128, u256>(x, 128)
}

/// Try to convert a `u128` to a `u8`. Returns `None` if the value is too large.
public fun try_as_u8(x: u128): Option<u8> {
std::macros::try_as_u8!(x)
}

/// Try to convert a `u128` to a `u16`. Returns `None` if the value is too large.
public fun try_as_u16(x: u128): Option<u16> {
std::macros::try_as_u16!(x)
}

/// Try to convert a `u128` to a `u32`. Returns `None` if the value is too large.
public fun try_as_u32(x: u128): Option<u32> {
std::macros::try_as_u32!(x)
}

/// Try to convert a `u128` to a `u64`. Returns `None` if the value is too large.
public fun try_as_u64(x: u128): Option<u64> {
std::macros::try_as_u64!(x)
}

public fun to_string(x: u128): String {
std::macros::num_to_string!(x)
}

/// Maximum value for a `u128`
public macro fun max_value(): u128 {
0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF
}

/// Loops applying `$f` to each number from `$start` to `$stop` (exclusive)
public macro fun range_do($start: u128, $stop: u128, $f: |u128|) {
std::macros::range_do!($start, $stop, $f)
Expand Down
Loading

0 comments on commit 369d44b

Please sign in to comment.