[m-rev.] for review: add functions for setting and testing individual bits of uint32s

Julien Fischer jfischer at opturion.com
Fri Apr 9 21:53:21 AEST 2021


For review by anyone.

My intention is to add this for all fixed size unsigned integer types; 
I'll add the others once this is reviewed and committed.

----------------------------

Add functions for setting and testing individual bits of uint32s.

library/uint32.m:
     Add functions for setting, clearing, flipping and testing
     the individual bits of a uint32 value.

NEWS:
     Announce the new functions.

tests/hard_coded/Mmakefile:
tests/hard_coded/bit_access_uint32.{m,exp}:
     Add a test case.

Julien.


diff --git a/NEWS b/NEWS
index 6caf99786..66f8243bb 100644
--- a/NEWS
+++ b/NEWS
@@ -305,6 +305,16 @@ Changes to the Mercury standard library
      - func `rotate_right/2`
      - func `unchecked_rotate_left/2`
      - func `unchecked_rotate_right/2`
+    - func `set_bit/2`
+    - func `unchecked_set_bit/2`
+    - func `clear_bit/2`
+    - func `unchecked_clear_bit/2`
+    - func `flip_bit/2`
+    - func `unchecked_flip_bit/2`
+    - func `bit_is_set/2`
+    - func `unchecked_bit_is_set/2`
+    - func `bit_is_clear/2`
+    - func `unchecked_bit_is_clear/2`

  ### Changes to the `uint64` module

diff --git a/library/uint32.m b/library/uint32.m
index 9d30c05b8..a515a3859 100644
--- a/library/uint32.m
+++ b/library/uint32.m
@@ -370,6 +370,62 @@
      %
  :- func unchecked_rotate_right(uint32, uint) = uint32.

+    % set_bit(U, I) = N:
+    % N is the value obtained by setting the I'th bit of U to one.
+    % An exception is thrown if I is not in [0, 31].
+    %
+:- func set_bit(uint32, uint) = uint32.
+
+    % unchecked_set_bit(U, I) = N:
+    % As above, but the behaviour is undefined if I is not in [0, 31].
+    %
+:- func unchecked_set_bit(uint32, uint) = uint32.
+
+    % clear_bit(U, I) = N:
+    % N is the value obtained by setting the I'th bit of U to zero.
+    % An exception is thrown if I is not in [0, 31].
+    %
+:- func clear_bit(uint32, uint) = uint32.
+
+    % unchecked_clear_bit(U, I) = N:
+    % As above, but the behaviour is undefined if I is not in [0, 31].
+    %
+:- func unchecked_clear_bit(uint32, uint) = uint32.
+
+    % flip_bit(U, I) = N:
+    % N is the value obtained by flipping the I'th bit of U.
+    % An exception is thrown if I is not in [0, 31].
+    %
+:- func flip_bit(uint32, uint) = uint32.
+
+    % unchecked_flip_bit(U, I) = N:
+    % N is the value obtained by flipping the I'th bit of U.
+    % An exception is thrown if I is not in [0, 31].
+    %
+:- func unchecked_flip_bit(uint32, uint) = uint32.
+
+    % bit_is_set(U, I):
+    % True iff the I'th bit of U is one.
+    % An exception is thrown if I is not in [0, 31].
+    %
+:- pred bit_is_set(uint32::in, uint::in) is semidet.
+
+    % unchecked_bit_is_set(U, I):
+    % As above, but the behaviour is undefined if I is not in [0, 31].
+    %
+:- pred unchecked_bit_is_set(uint32::in, uint::in) is semidet.
+
+    % bit_is_clear(U, I):
+    % True iff the I'th bit of U is zero.
+    % An exception is thrown if I is not in [0, 31].
+    %
+:- pred bit_is_clear(uint32::in, uint::in) is semidet.
+
+    % unchecked_bit_is_clear(U, I):
+    % As above, but the behaviour is undefined if I is not in [0, 31].
+    %
+:- pred unchecked_bit_is_clear(uint32::in, uint::in) is semidet.
+
  %---------------------------------------------------------------------------%
  %
  % Limits.
@@ -971,6 +1027,59 @@ rotate_right(X, N) =

  %---------------------------------------------------------------------------%

+set_bit(U, I) =
+    ( if I < 32u then
+        unchecked_set_bit(U, I)
+    else
+        func_error($pred, "bit index exceeds 31 bits")
+    ).
+
+unchecked_set_bit(U, I) =
+    U \/ (1u32 `unchecked_left_shift` cast_to_int(I)).
+
+clear_bit(U, I) =
+    ( if I < 32u then
+        unchecked_clear_bit(U, I)
+    else
+        func_error($pred, "bit index exceeds 31 bits")
+    ).
+
+unchecked_clear_bit(U, I) =
+    U /\ (\ (1u32 `unchecked_left_shift` cast_to_int(I))).
+
+
+flip_bit(U, I) =
+    ( if I < 32u then
+        unchecked_flip_bit(U, I)
+    else
+        func_error($pred, "bit index exceeds 31 bits")
+    ).
+
+unchecked_flip_bit(U, I) =
+    U `xor` (1u32 `unchecked_left_shift` cast_to_int(I)).
+
+bit_is_set(U, I) :-
+    ( if I < 32u then
+        unchecked_bit_is_set(U, I)
+    else
+        error($pred, "bit index exceeds 31 bits")
+    ).
+
+unchecked_bit_is_set(U, I) :-
+    U /\ (1u32 `unchecked_left_shift` cast_to_int(I)) \= 0u32.
+
+bit_is_clear(U, I) :-
+    ( if I < 32u then
+        unchecked_bit_is_clear(U, I)
+    else
+        error($pred, "bit index exceeds 31 bits")
+    ).
+
+unchecked_bit_is_clear(U, I) :-
+    U /\ (1u32 `unchecked_left_shift` cast_to_int(I)) = 0u32.
+
+%---------------------------------------------------------------------------%
+
  max_uint32 = 4_294_967_295_u32.

  %---------------------------------------------------------------------------%
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index c0ac6f7ae..d12ce07af 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -746,6 +746,7 @@ ifeq "$(findstring profdeep,$(GRADE))" ""
  		arith_uint32 \
  		arith_uint64 \
  		arith_uint8 \
+		bit_access_uint32 \
  		bitmap_bytes \
  		bitmap_empty \
  		bitmap_test \
diff --git a/tests/hard_coded/bit_access_uint32.exp b/tests/hard_coded/bit_access_uint32.exp
index e69de29bb..a6dd5aecd 100644
--- a/tests/hard_coded/bit_access_uint32.exp
+++ b/tests/hard_coded/bit_access_uint32.exp
@@ -0,0 +1,183 @@
+*** Test operation 'set_bit' ***
+
+set_bit(00000000000000000000000000000000, 0) = 00000000000000000000000000000001
+set_bit(00000000000000000000000000000000, 1) = 00000000000000000000000000000010
+set_bit(00000000000000000000000000000000, 2) = 00000000000000000000000000000100
+set_bit(00000000000000000000000000000000, 7) = 00000000000000000000000010000000
+set_bit(00000000000000000000000000000000, 15) = 00000000000000001000000000000000
+set_bit(00000000000000000000000000000000, 31) = 10000000000000000000000000000000
+set_bit(00000000000000000000000000000000, 32) = <<exception>>
+set_bit(11111111111111111111111111111111, 0) = 11111111111111111111111111111111
+set_bit(11111111111111111111111111111111, 1) = 11111111111111111111111111111111
+set_bit(11111111111111111111111111111111, 2) = 11111111111111111111111111111111
+set_bit(11111111111111111111111111111111, 7) = 11111111111111111111111111111111
+set_bit(11111111111111111111111111111111, 15) = 11111111111111111111111111111111
+set_bit(11111111111111111111111111111111, 31) = 11111111111111111111111111111111
+set_bit(11111111111111111111111111111111, 32) = <<exception>>
+
+*** Test operation 'clear_bit' ***
+
+clear_bit(00000000000000000000000000000000, 0) = 00000000000000000000000000000000
+clear_bit(00000000000000000000000000000000, 1) = 00000000000000000000000000000000
+clear_bit(00000000000000000000000000000000, 2) = 00000000000000000000000000000000
+clear_bit(00000000000000000000000000000000, 7) = 00000000000000000000000000000000
+clear_bit(00000000000000000000000000000000, 15) = 00000000000000000000000000000000
+clear_bit(00000000000000000000000000000000, 31) = 00000000000000000000000000000000
+clear_bit(00000000000000000000000000000000, 32) = <<exception>>
+clear_bit(11111111111111111111111111111111, 0) = 11111111111111111111111111111110
+clear_bit(11111111111111111111111111111111, 1) = 11111111111111111111111111111101
+clear_bit(11111111111111111111111111111111, 2) = 11111111111111111111111111111011
+clear_bit(11111111111111111111111111111111, 7) = 11111111111111111111111101111111
+clear_bit(11111111111111111111111111111111, 15) = 11111111111111110111111111111111
+clear_bit(11111111111111111111111111111111, 31) = 01111111111111111111111111111111
+clear_bit(11111111111111111111111111111111, 32) = <<exception>>
+
+*** Test operation 'flip_bit' ***
+
+flip_bit(00000000000000000000000000000000, 0) = 00000000000000000000000000000001
+flip_bit(00000000000000000000000000000000, 1) = 00000000000000000000000000000010
+flip_bit(00000000000000000000000000000000, 2) = 00000000000000000000000000000100
+flip_bit(00000000000000000000000000000000, 7) = 00000000000000000000000010000000
+flip_bit(00000000000000000000000000000000, 15) = 00000000000000001000000000000000
+flip_bit(00000000000000000000000000000000, 31) = 10000000000000000000000000000000
+flip_bit(00000000000000000000000000000000, 32) = <<exception>>
+flip_bit(11111111111111111111111111111111, 0) = 11111111111111111111111111111110
+flip_bit(11111111111111111111111111111111, 1) = 11111111111111111111111111111101
+flip_bit(11111111111111111111111111111111, 2) = 11111111111111111111111111111011
+flip_bit(11111111111111111111111111111111, 7) = 11111111111111111111111101111111
+flip_bit(11111111111111111111111111111111, 15) = 11111111111111110111111111111111
+flip_bit(11111111111111111111111111111111, 31) = 01111111111111111111111111111111
+flip_bit(11111111111111111111111111111111, 32) = <<exception>>
+
+*** Test operation 'bit_is_set' ***
+
+bit_is_set(00000000000000000000000000000000, 0) ==> false
+bit_is_set(00000000000000000000000000000000, 1) ==> false
+bit_is_set(00000000000000000000000000000000, 2) ==> false
+bit_is_set(00000000000000000000000000000000, 7) ==> false
+bit_is_set(00000000000000000000000000000000, 15) ==> false
+bit_is_set(00000000000000000000000000000000, 31) ==> false
+bit_is_set(00000000000000000000000000000000, 32) ==> <<exception>>
+bit_is_set(00000000000000000000000000000001, 0) ==> true
+bit_is_set(00000000000000000000000000000001, 1) ==> false
+bit_is_set(00000000000000000000000000000001, 2) ==> false
+bit_is_set(00000000000000000000000000000001, 7) ==> false
+bit_is_set(00000000000000000000000000000001, 15) ==> false
+bit_is_set(00000000000000000000000000000001, 31) ==> false
+bit_is_set(00000000000000000000000000000001, 32) ==> <<exception>>
+bit_is_set(00000000000000000000000000000010, 0) ==> false
+bit_is_set(00000000000000000000000000000010, 1) ==> true
+bit_is_set(00000000000000000000000000000010, 2) ==> false
+bit_is_set(00000000000000000000000000000010, 7) ==> false
+bit_is_set(00000000000000000000000000000010, 15) ==> false
+bit_is_set(00000000000000000000000000000010, 31) ==> false
+bit_is_set(00000000000000000000000000000010, 32) ==> <<exception>>
+bit_is_set(00000000000000000000000000001000, 0) ==> false
+bit_is_set(00000000000000000000000000001000, 1) ==> false
+bit_is_set(00000000000000000000000000001000, 2) ==> false
+bit_is_set(00000000000000000000000000001000, 7) ==> false
+bit_is_set(00000000000000000000000000001000, 15) ==> false
+bit_is_set(00000000000000000000000000001000, 31) ==> false
+bit_is_set(00000000000000000000000000001000, 32) ==> <<exception>>
+bit_is_set(00000000000000000000000000001010, 0) ==> false
+bit_is_set(00000000000000000000000000001010, 1) ==> true
+bit_is_set(00000000000000000000000000001010, 2) ==> false
+bit_is_set(00000000000000000000000000001010, 7) ==> false
+bit_is_set(00000000000000000000000000001010, 15) ==> false
+bit_is_set(00000000000000000000000000001010, 31) ==> false
+bit_is_set(00000000000000000000000000001010, 32) ==> <<exception>>
+bit_is_set(00000000000000000000000000010000, 0) ==> false
+bit_is_set(00000000000000000000000000010000, 1) ==> false
+bit_is_set(00000000000000000000000000010000, 2) ==> false
+bit_is_set(00000000000000000000000000010000, 7) ==> false
+bit_is_set(00000000000000000000000000010000, 15) ==> false
+bit_is_set(00000000000000000000000000010000, 31) ==> false
+bit_is_set(00000000000000000000000000010000, 32) ==> <<exception>>
+bit_is_set(00000000000000000000000011111111, 0) ==> true
+bit_is_set(00000000000000000000000011111111, 1) ==> true
+bit_is_set(00000000000000000000000011111111, 2) ==> true
+bit_is_set(00000000000000000000000011111111, 7) ==> true
+bit_is_set(00000000000000000000000011111111, 15) ==> false
+bit_is_set(00000000000000000000000011111111, 31) ==> false
+bit_is_set(00000000000000000000000011111111, 32) ==> <<exception>>
+bit_is_set(00000000000000001111111111111111, 0) ==> true
+bit_is_set(00000000000000001111111111111111, 1) ==> true
+bit_is_set(00000000000000001111111111111111, 2) ==> true
+bit_is_set(00000000000000001111111111111111, 7) ==> true
+bit_is_set(00000000000000001111111111111111, 15) ==> true
+bit_is_set(00000000000000001111111111111111, 31) ==> false
+bit_is_set(00000000000000001111111111111111, 32) ==> <<exception>>
+bit_is_set(11111111111111111111111111111111, 0) ==> true
+bit_is_set(11111111111111111111111111111111, 1) ==> true
+bit_is_set(11111111111111111111111111111111, 2) ==> true
+bit_is_set(11111111111111111111111111111111, 7) ==> true
+bit_is_set(11111111111111111111111111111111, 15) ==> true
+bit_is_set(11111111111111111111111111111111, 31) ==> true
+bit_is_set(11111111111111111111111111111111, 32) ==> <<exception>>
+
+*** Test operation 'bit_is_clear' ***
+
+bit_is_clear(00000000000000000000000000000000, 0) ==> true
+bit_is_clear(00000000000000000000000000000000, 1) ==> true
+bit_is_clear(00000000000000000000000000000000, 2) ==> true
+bit_is_clear(00000000000000000000000000000000, 7) ==> true
+bit_is_clear(00000000000000000000000000000000, 15) ==> true
+bit_is_clear(00000000000000000000000000000000, 31) ==> true
+bit_is_clear(00000000000000000000000000000000, 32) ==> <<exception>>
+bit_is_clear(00000000000000000000000000000001, 0) ==> false
+bit_is_clear(00000000000000000000000000000001, 1) ==> true
+bit_is_clear(00000000000000000000000000000001, 2) ==> true
+bit_is_clear(00000000000000000000000000000001, 7) ==> true
+bit_is_clear(00000000000000000000000000000001, 15) ==> true
+bit_is_clear(00000000000000000000000000000001, 31) ==> true
+bit_is_clear(00000000000000000000000000000001, 32) ==> <<exception>>
+bit_is_clear(00000000000000000000000000000010, 0) ==> true
+bit_is_clear(00000000000000000000000000000010, 1) ==> false
+bit_is_clear(00000000000000000000000000000010, 2) ==> true
+bit_is_clear(00000000000000000000000000000010, 7) ==> true
+bit_is_clear(00000000000000000000000000000010, 15) ==> true
+bit_is_clear(00000000000000000000000000000010, 31) ==> true
+bit_is_clear(00000000000000000000000000000010, 32) ==> <<exception>>
+bit_is_clear(00000000000000000000000000001000, 0) ==> true
+bit_is_clear(00000000000000000000000000001000, 1) ==> true
+bit_is_clear(00000000000000000000000000001000, 2) ==> true
+bit_is_clear(00000000000000000000000000001000, 7) ==> true
+bit_is_clear(00000000000000000000000000001000, 15) ==> true
+bit_is_clear(00000000000000000000000000001000, 31) ==> true
+bit_is_clear(00000000000000000000000000001000, 32) ==> <<exception>>
+bit_is_clear(00000000000000000000000000001010, 0) ==> true
+bit_is_clear(00000000000000000000000000001010, 1) ==> false
+bit_is_clear(00000000000000000000000000001010, 2) ==> true
+bit_is_clear(00000000000000000000000000001010, 7) ==> true
+bit_is_clear(00000000000000000000000000001010, 15) ==> true
+bit_is_clear(00000000000000000000000000001010, 31) ==> true
+bit_is_clear(00000000000000000000000000001010, 32) ==> <<exception>>
+bit_is_clear(00000000000000000000000000010000, 0) ==> true
+bit_is_clear(00000000000000000000000000010000, 1) ==> true
+bit_is_clear(00000000000000000000000000010000, 2) ==> true
+bit_is_clear(00000000000000000000000000010000, 7) ==> true
+bit_is_clear(00000000000000000000000000010000, 15) ==> true
+bit_is_clear(00000000000000000000000000010000, 31) ==> true
+bit_is_clear(00000000000000000000000000010000, 32) ==> <<exception>>
+bit_is_clear(00000000000000000000000011111111, 0) ==> false
+bit_is_clear(00000000000000000000000011111111, 1) ==> false
+bit_is_clear(00000000000000000000000011111111, 2) ==> false
+bit_is_clear(00000000000000000000000011111111, 7) ==> false
+bit_is_clear(00000000000000000000000011111111, 15) ==> true
+bit_is_clear(00000000000000000000000011111111, 31) ==> true
+bit_is_clear(00000000000000000000000011111111, 32) ==> <<exception>>
+bit_is_clear(00000000000000001111111111111111, 0) ==> false
+bit_is_clear(00000000000000001111111111111111, 1) ==> false
+bit_is_clear(00000000000000001111111111111111, 2) ==> false
+bit_is_clear(00000000000000001111111111111111, 7) ==> false
+bit_is_clear(00000000000000001111111111111111, 15) ==> false
+bit_is_clear(00000000000000001111111111111111, 31) ==> true
+bit_is_clear(00000000000000001111111111111111, 32) ==> <<exception>>
+bit_is_clear(11111111111111111111111111111111, 0) ==> false
+bit_is_clear(11111111111111111111111111111111, 1) ==> false
+bit_is_clear(11111111111111111111111111111111, 2) ==> false
+bit_is_clear(11111111111111111111111111111111, 7) ==> false
+bit_is_clear(11111111111111111111111111111111, 15) ==> false
+bit_is_clear(11111111111111111111111111111111, 31) ==> false
+bit_is_clear(11111111111111111111111111111111, 32) ==> <<exception>>
+
diff --git a/tests/hard_coded/bit_access_uint32.m b/tests/hard_coded/bit_access_uint32.m
index e69de29bb..5290bd680 100644
--- a/tests/hard_coded/bit_access_uint32.m
+++ b/tests/hard_coded/bit_access_uint32.m
@@ -0,0 +1,177 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%---------------------------------------------------------------------------%
+
+% Test look ups and setting of individual bits for uint32s.
+
+:- module bit_access_uint32.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is cc_multi.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module uint32.
+
+:- import_module exception.
+:- import_module list.
+:- import_module string.
+
+%---------------------------------------------------------------------------%
+
+main(!IO) :-
+    run_modify_test(uint32.set_bit, "set_bit", !IO),
+    io.nl(!IO),
+    run_modify_test(uint32.clear_bit, "clear_bit", !IO),
+    io.nl(!IO),
+    run_modify_test(uint32.flip_bit, "flip_bit", !IO),
+    io.nl(!IO),
+    run_value_test(uint32.bit_is_set, "bit_is_set", !IO),
+    io.nl(!IO),
+    run_value_test(uint32.bit_is_clear, "bit_is_clear", !IO),
+    io.nl(!IO).
+
+%---------------------------------------------------------------------------%
+
+:- pred run_modify_test((func(uint32, uint) = uint32)::in, string::in,
+    io::di, io::uo) is cc_multi.
+
+run_modify_test(Func, Desc, !IO) :-
+    io.format("*** Test operation '%s' ***\n\n", [s(Desc)], !IO),
+    list.foldl(run_modify_test_2(Func, Desc), modify_numbers, !IO).
+
+:- pred run_modify_test_2((func(uint32, uint) = uint32)::in, string::in,
+    uint32::in, io::di, io::uo) is cc_multi.
+
+run_modify_test_2(Func, Desc, U, !IO) :-
+    list.foldl(run_modify_test_3(Func, Desc, U), bit_indexes, !IO).
+
+:- pred run_modify_test_3((func(uint32, uint) = uint32)::in, string::in,
+    uint32::in, uint::in, io::di, io::uo) is cc_multi.
+
+run_modify_test_3(Func, Desc, U, I, !IO) :-
+    ( try []
+        Result0 = Func(U, I)
+    then
+        ResultStr = to_binary_string_lz(Result0)
+    catch_any _ ->
+        ResultStr = "<<exception>>"
+    ),
+    io.format("%s(%s, %u) = %s\n",
+        [s(Desc),
+        s(to_binary_string_lz(U)),
+        u(I),
+        s(ResultStr)], !IO).
+
+%---------------------------------------------------------------------------%
+
+:- pred run_value_test(pred(uint32, uint)::in(pred(in, in) is semidet),
+    string::in, io::di, io::uo) is cc_multi.
+
+run_value_test(Pred, Desc, !IO) :-
+    io.format("*** Test operation '%s' ***\n\n", [s(Desc)], !IO),
+    list.foldl(run_value_test_2(Pred, Desc), test_numbers, !IO).
+
+:- pred run_value_test_2(pred(uint32, uint)::in(pred(in, in) is semidet),
+    string::in, uint32::in, io::di, io::uo) is cc_multi.
+
+run_value_test_2(Pred, Desc, U, !IO) :-
+    list.foldl(run_value_test_3(Pred, Desc, U), bit_indexes, !IO).
+
+:- pred run_value_test_3(pred(uint32, uint)::in(pred(in, in) is semidet),
+    string::in, uint32::in, uint::in, io::di, io::uo) is cc_multi.
+
+run_value_test_3(Pred, Desc, U, I, !IO) :-
+    ( try []
+        Pred(U, I)
+    then
+        ResultStr = "true"
+    else
+        ResultStr = "false"
+    catch_any _ ->
+        ResultStr = "<<exception>>"
+    ),
+    io.format("%s(%s, %u) ==> %s\n",
+        [s(Desc),
+        s(to_binary_string_lz(U)),
+        u(I),
+        s(ResultStr)], !IO).
+
+%---------------------------------------------------------------------------%
+
+:- func modify_numbers = list(uint32).
+
+modify_numbers = [
+   0_u32,
+   4_294_967_295_u32
+].
+
+:- func test_numbers = list(uint32).
+
+test_numbers = [
+    0_u32,
+    1_u32,
+    2_u32,
+    8_u32,
+    10_u32,
+    16_u32,
+    255_u32,
+    65_535_u32,
+    4_294_967_295_u32
+].
+
+:- func bit_indexes = list(uint).
+
+bit_indexes = [
+   0_u,
+   1_u,
+   2_u,
+   7_u,
+   15_u,
+   31_u,
+   32_u
+].
+
+%---------------------------------------------------------------------------%
+
+:- func to_binary_string_lz(uint32::in) = (string::uo) is det.
+
+:- pragma foreign_proc("C",
+    to_binary_string_lz(U::in) = (S::uo),
+    [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+    int i = 32;
+
+    MR_allocate_aligned_string_msg(S, 32, MR_ALLOC_ID);
+    S[32] = '\\0';
+    while (i > 0) {
+        i--;
+        S[i] = (U & 1) ? '1' : '0';
+        U = U >> 1;
+    }
+").
+
+:- pragma foreign_proc("C#",
+    to_binary_string_lz(U::in) = (S::uo),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    S = System.Convert.ToString(U, 2).PadLeft(32, '0');
+").
+
+:- pragma foreign_proc("Java",
+    to_binary_string_lz(U::in) = (S::uo),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    S = java.lang.String.format(""%32s"",
+        java.lang.Integer.toBinaryString(U)).replace(' ', '0');
+").
+
+%---------------------------------------------------------------------------%
+:- end_module bit_access_uint32.
+%---------------------------------------------------------------------------%
+


More information about the reviews mailing list