mirror of
https://github.com/tailix/libkernaux.git
synced 2025-04-07 17:32:45 -04:00
Main: include/kernaux/ntoa.h: Add binary functions "kernaux_[u|i]toa2"
This commit is contained in:
parent
4ea9f7b36f
commit
ff29456300
14 changed files with 457 additions and 4 deletions
|
@ -9,6 +9,7 @@
|
|||
of a buffer
|
||||
* include/kernaux/ntoa.h: Functions "kernaux_[u|i]toa16" put default prefix
|
||||
* include/kernaux/ntoa.h: Add octal functions "kernaux_[u|i]toa8"
|
||||
* include/kernaux/ntoa.h: Add binary functions "kernaux_[u|i]toa2"
|
||||
|
||||
2022-05-28 Alex Kotov <kotovalexarian@gmail.com>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ extern "C" {
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#define KERNAUX_NTOA_DEFAULT_PREFIX_2 "0b"
|
||||
#define KERNAUX_NTOA_DEFAULT_PREFIX_8 "0o"
|
||||
#define KERNAUX_NTOA_DEFAULT_PREFIX_16 "0x"
|
||||
|
||||
|
@ -17,6 +18,13 @@ extern "C" {
|
|||
// "-1000000000000000000000000000000000000000000000000000000000000000"
|
||||
#define KERNAUX_ITOA_MIN_BUFFER_SIZE (65 + 1)
|
||||
|
||||
// "0b1111111111111111111111111111111111111111111111111111111111111111"
|
||||
#define KERNAUX_UTOA2_BUFFER_SIZE (64 + 2 + 1)
|
||||
|
||||
// "0b111111111111111111111111111111111111111111111111111111111111111"
|
||||
// "-0b1000000000000000000000000000000000000000000000000000000000000000"
|
||||
#define KERNAUX_ITOA2_BUFFER_SIZE (65 + 2 + 1)
|
||||
|
||||
// "0o1777777777777777777777"
|
||||
#define KERNAUX_UTOA8_BUFFER_SIZE (21 + 2 + 1)
|
||||
|
||||
|
@ -41,6 +49,9 @@ extern "C" {
|
|||
char *kernaux_utoa(uint64_t value, char *buffer, int base, const char *prefix);
|
||||
char *kernaux_itoa(int64_t value, char *buffer, int base, const char *prefix);
|
||||
|
||||
char *kernaux_utoa2(uint64_t value, char *buffer);
|
||||
char *kernaux_itoa2(int64_t value, char *buffer);
|
||||
|
||||
char *kernaux_utoa8(uint64_t value, char *buffer);
|
||||
char *kernaux_itoa8(int64_t value, char *buffer);
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
static mrb_value rb_KernAux_utoa(mrb_state *mrb, mrb_value self);
|
||||
static mrb_value rb_KernAux_itoa(mrb_state *mrb, mrb_value self);
|
||||
|
||||
static mrb_value rb_KernAux_utoa2(mrb_state *mrb, mrb_value self);
|
||||
static mrb_value rb_KernAux_itoa2(mrb_state *mrb, mrb_value self);
|
||||
|
||||
static mrb_value rb_KernAux_utoa8(mrb_state *mrb, mrb_value self);
|
||||
static mrb_value rb_KernAux_itoa8(mrb_state *mrb, mrb_value self);
|
||||
|
||||
|
@ -41,6 +44,11 @@ void init_ntoa(mrb_state *const mrb)
|
|||
mrb_define_class_method(mrb, rb_KernAux, "itoa",
|
||||
rb_KernAux_itoa, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
|
||||
|
||||
mrb_define_class_method(mrb, rb_KernAux, "utoa2",
|
||||
rb_KernAux_utoa2, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, rb_KernAux, "itoa2",
|
||||
rb_KernAux_itoa2, MRB_ARGS_REQ(1));
|
||||
|
||||
mrb_define_class_method(mrb, rb_KernAux, "utoa8",
|
||||
rb_KernAux_utoa8, MRB_ARGS_REQ(1));
|
||||
mrb_define_class_method(mrb, rb_KernAux, "itoa8",
|
||||
|
@ -123,6 +131,41 @@ mrb_value rb_KernAux_itoa(mrb_state *mrb, mrb_value self)
|
|||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_utoa2(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
mrb_get_args(mrb, "i", &value);
|
||||
|
||||
if (value < 0) {
|
||||
mrb_raise(mrb, E_RANGE_ERROR,
|
||||
"can't convert negative number to uint64_t");
|
||||
}
|
||||
|
||||
char buffer[KERNAUX_UTOA2_BUFFER_SIZE];
|
||||
current_mrb_start(mrb);
|
||||
kernaux_utoa2(value, buffer);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
result = mrb_str_cat_cstr(mrb, result, buffer);
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_itoa2(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
mrb_get_args(mrb, "i", &value);
|
||||
|
||||
char buffer[KERNAUX_ITOA2_BUFFER_SIZE];
|
||||
current_mrb_start(mrb);
|
||||
kernaux_itoa2(value, buffer);
|
||||
current_mrb_finish(mrb);
|
||||
|
||||
mrb_value result = mrb_str_new_lit(mrb, "");
|
||||
result = mrb_str_cat_cstr(mrb, result, buffer);
|
||||
return mrb_obj_freeze(mrb, result);
|
||||
}
|
||||
|
||||
mrb_value rb_KernAux_utoa8(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int value = 0;
|
||||
|
|
|
@ -24,6 +24,14 @@ def test_itoax(number, base, prefix, expected)
|
|||
common_assert expected, KernAux.itoa(number, base, prefix)
|
||||
end
|
||||
|
||||
def test_utoa2(number, expected)
|
||||
common_assert expected, KernAux.utoa2(number)
|
||||
end
|
||||
|
||||
def test_itoa2(number, expected)
|
||||
common_assert expected, KernAux.itoa2(number)
|
||||
end
|
||||
|
||||
def test_utoa8(number, expected)
|
||||
common_assert expected, KernAux.utoa8(number)
|
||||
end
|
||||
|
@ -203,6 +211,27 @@ assert 'KernAux.itoa' do
|
|||
end
|
||||
end
|
||||
|
||||
assert 'KernAux.utoa2' do
|
||||
test_utoa2 0, '0b0'
|
||||
test_utoa2 1, '0b1'
|
||||
test_utoa2 123, '0b1111011'
|
||||
test_utoa2 2**32 - 1, "0b#{(2**32 - 1).to_s(2)}"
|
||||
|
||||
assert_raise RangeError, 'can\'t convert negative number to uint64_t' do
|
||||
KernAux.utoa2(-1)
|
||||
end
|
||||
end
|
||||
|
||||
assert 'KernAux.itoa2' do
|
||||
test_itoa2 0, '0b0'
|
||||
test_itoa2 1, '0b1'
|
||||
test_itoa2(-1, '-0b1')
|
||||
test_itoa2 123, '0b1111011'
|
||||
test_itoa2(-123, '-0b1111011')
|
||||
test_itoa2 2**31 - 1, "0b#{(2**31 - 1).to_s(2)}"
|
||||
test_itoa2(-2**31, "-0b#{(2**31).to_s(2)}")
|
||||
end
|
||||
|
||||
assert 'KernAux.utoa8' do
|
||||
test_utoa8 0, '0o0'
|
||||
test_utoa8 0o1, '0o1'
|
||||
|
|
|
@ -13,6 +13,8 @@ end
|
|||
|
||||
have_func 'kernaux_utoa'
|
||||
have_func 'kernaux_itoa'
|
||||
have_func 'kernaux_utoa2'
|
||||
have_func 'kernaux_itoa2'
|
||||
have_func 'kernaux_utoa8'
|
||||
have_func 'kernaux_itoa8'
|
||||
have_func 'kernaux_utoa10'
|
||||
|
|
|
@ -9,6 +9,12 @@ static VALUE rb_KernAux_utoa(int argc, const VALUE *argv, VALUE self);
|
|||
#ifdef HAVE_KERNAUX_ITOA
|
||||
static VALUE rb_KernAux_itoa(int argc, const VALUE *argv, VALUE self);
|
||||
#endif
|
||||
#ifdef HAVE_KERNAUX_UTOA2
|
||||
static VALUE rb_KernAux_utoa2(VALUE self, VALUE number);
|
||||
#endif
|
||||
#ifdef HAVE_KERNAUX_ITOA2
|
||||
static VALUE rb_KernAux_itoa2(VALUE self, VALUE number);
|
||||
#endif
|
||||
#ifdef HAVE_KERNAUX_UTOA8
|
||||
static VALUE rb_KernAux_utoa8(VALUE self, VALUE number);
|
||||
#endif
|
||||
|
@ -81,6 +87,12 @@ void init_ntoa()
|
|||
#ifdef HAVE_KERNAUX_ITOA
|
||||
rb_define_singleton_method(rb_KernAux, "itoa", rb_KernAux_itoa, -1);
|
||||
#endif
|
||||
#ifdef HAVE_KERNAUX_UTOA2
|
||||
rb_define_singleton_method(rb_KernAux, "utoa2", rb_KernAux_utoa2, 1);
|
||||
#endif
|
||||
#ifdef HAVE_KERNAUX_ITOA2
|
||||
rb_define_singleton_method(rb_KernAux, "itoa2", rb_KernAux_itoa2, 1);
|
||||
#endif
|
||||
#ifdef HAVE_KERNAUX_UTOA8
|
||||
rb_define_singleton_method(rb_KernAux, "utoa8", rb_KernAux_utoa8, 1);
|
||||
#endif
|
||||
|
@ -180,6 +192,33 @@ VALUE rb_KernAux_itoa(const int argc, const VALUE *argv, const VALUE self)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_KERNAUX_UTOA2
|
||||
VALUE rb_KernAux_utoa2(
|
||||
const VALUE self_rb __attribute__((unused)),
|
||||
const VALUE number_rb
|
||||
) {
|
||||
RB_INTEGER_TYPE_P(number_rb);
|
||||
if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) {
|
||||
rb_raise(rb_eRangeError, "can't convert negative number to uint64_t");
|
||||
}
|
||||
char buffer[KERNAUX_UTOA2_BUFFER_SIZE];
|
||||
kernaux_utoa2(NUM2ULL(number_rb), buffer);
|
||||
return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_KERNAUX_ITOA2
|
||||
VALUE rb_KernAux_itoa2(
|
||||
const VALUE self_rb __attribute__((unused)),
|
||||
const VALUE number_rb
|
||||
) {
|
||||
RB_INTEGER_TYPE_P(number_rb);
|
||||
char buffer[KERNAUX_ITOA2_BUFFER_SIZE];
|
||||
kernaux_itoa2(NUM2LL(number_rb), buffer);
|
||||
return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_KERNAUX_UTOA8
|
||||
VALUE rb_KernAux_utoa8(
|
||||
const VALUE self_rb __attribute__((unused)),
|
||||
|
|
|
@ -172,6 +172,26 @@ module KernAux
|
|||
# @see .utoa Convert unsigned integers
|
||||
##
|
||||
|
||||
##
|
||||
# @!method utoa2(number)
|
||||
# Convert `uint64_t` to a binary string.
|
||||
#
|
||||
# @param number [Integer] a number between 0 and `UINT64_MAX`
|
||||
# @return [String]
|
||||
#
|
||||
# @raise [RangeError] number is out of range
|
||||
##
|
||||
|
||||
##
|
||||
# @!method itoa2(number)
|
||||
# Convert `int64_t` to a binary string.
|
||||
#
|
||||
# @param number [Integer] a number between `INT64_MIN` and `INT64_MAX`
|
||||
# @return [String]
|
||||
#
|
||||
# @raise [RangeError] number is out of range
|
||||
##
|
||||
|
||||
##
|
||||
# @!method utoa8(number)
|
||||
# Convert `uint64_t` to a octal string.
|
||||
|
|
65
pkgs/ruby/spec/lib/kernaux/itoa2_spec.rb
Normal file
65
pkgs/ruby/spec/lib/kernaux/itoa2_spec.rb
Normal file
|
@ -0,0 +1,65 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe KernAux, '.itoa2' do
|
||||
if described_class.singleton_class.method_defined? :itoa2
|
||||
subject(:itoa2) { described_class.itoa2 number }
|
||||
|
||||
let(:number) { rand((-2**63)..(2**63 - 1)) }
|
||||
|
||||
def sign = number < 0 ? '-' : ''
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq "#{sign}0b#{number.abs.to_s(2)}" }
|
||||
|
||||
context 'when number is 0' do
|
||||
let(:number) { 0 }
|
||||
|
||||
it { is_expected.to eq '0b0' }
|
||||
end
|
||||
|
||||
context 'when number is 1' do
|
||||
let(:number) { 1 }
|
||||
|
||||
it { is_expected.to eq '0b1' }
|
||||
end
|
||||
|
||||
context 'when number is -1' do
|
||||
let(:number) { -1 }
|
||||
|
||||
it { is_expected.to eq '-0b1' }
|
||||
end
|
||||
|
||||
context 'when number is min int64_t' do
|
||||
let(:number) { -2**63 }
|
||||
|
||||
it { is_expected.to eq "-0b#{number.abs.to_s(2)}" }
|
||||
end
|
||||
|
||||
context 'when number is max int64_t' do
|
||||
let(:number) { 2**63 - 1 }
|
||||
|
||||
it { is_expected.to eq "0b#{number.to_s(2)}" }
|
||||
end
|
||||
|
||||
context 'when number is lesser than min uint64_t' do
|
||||
let(:number) { -2**63 - 1 }
|
||||
|
||||
specify do
|
||||
expect { itoa2 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `long long\''
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is greater than max uint64_t' do
|
||||
let(:number) { 2**63 }
|
||||
|
||||
specify do
|
||||
expect { itoa2 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `long long\''
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
45
pkgs/ruby/spec/lib/kernaux/utoa2_spec.rb
Normal file
45
pkgs/ruby/spec/lib/kernaux/utoa2_spec.rb
Normal file
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe KernAux, '.utoa2' do
|
||||
if described_class.singleton_class.method_defined? :utoa2
|
||||
subject(:utoa2) { described_class.utoa2 number }
|
||||
|
||||
let(:number) { rand 0..(2**64 - 1) }
|
||||
|
||||
it { is_expected.to be_instance_of String }
|
||||
it { is_expected.to be_frozen }
|
||||
it { is_expected.to eq "0b#{number.to_s(2)}" }
|
||||
|
||||
context 'when number is 0' do
|
||||
let(:number) { 0 }
|
||||
|
||||
it { is_expected.to eq '0b0' }
|
||||
end
|
||||
|
||||
context 'when number is max uint64_t' do
|
||||
let(:number) { 2**64 - 1 }
|
||||
|
||||
it { is_expected.to eq "0b#{number.to_s(2)}" }
|
||||
end
|
||||
|
||||
context 'when number is -1' do
|
||||
let(:number) { -1 }
|
||||
|
||||
specify do
|
||||
expect { utoa2 }.to \
|
||||
raise_error RangeError, 'can\'t convert negative number to uint64_t'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when number is greater than max uint64_t' do
|
||||
let(:number) { 2**64 }
|
||||
|
||||
specify do
|
||||
expect { utoa2 }.to raise_error \
|
||||
RangeError, 'bignum too big to convert into `unsigned long long\''
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,6 +3,8 @@ use libc::{c_char, c_int};
|
|||
pub const UTOA_MIN_BUFFER_SIZE: usize = 64 + 1;
|
||||
pub const ITOA_MIN_BUFFER_SIZE: usize = 65 + 1;
|
||||
|
||||
pub const UTOA2_BUFFER_SIZE: usize = 64 + 2 + 1;
|
||||
pub const ITOA2_BUFFER_SIZE: usize = 65 + 2 + 1;
|
||||
pub const UTOA8_BUFFER_SIZE: usize = 21 + 2 + 1;
|
||||
pub const ITOA8_BUFFER_SIZE: usize = 22 + 2 + 1;
|
||||
pub const UTOA10_BUFFER_SIZE: usize = 20 + 1;
|
||||
|
@ -27,6 +29,10 @@ extern "C" {
|
|||
prefix: *const c_char,
|
||||
) -> *mut c_char;
|
||||
|
||||
#[link_name = "kernaux_utoa2"]
|
||||
pub fn utoa2(value: u64, buffer: *mut c_char) -> *mut c_char;
|
||||
#[link_name = "kernaux_itoa2"]
|
||||
pub fn itoa2(value: i64, buffer: *mut c_char) -> *mut c_char;
|
||||
#[link_name = "kernaux_utoa8"]
|
||||
pub fn utoa8(value: u64, buffer: *mut c_char) -> *mut c_char;
|
||||
#[link_name = "kernaux_itoa8"]
|
||||
|
@ -148,6 +154,33 @@ mod tests {
|
|||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(7) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa2() {
|
||||
let mut buffer: [i8; UTOA2_BUFFER_SIZE] = [0; UTOA2_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { utoa2(123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "0b1111011");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(9) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa2() {
|
||||
let mut buffer: [i8; ITOA2_BUFFER_SIZE] = [0; ITOA2_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { itoa2(123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "0b1111011");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(9) });
|
||||
|
||||
let mut buffer: [i8; ITOA2_BUFFER_SIZE] = [0; ITOA2_BUFFER_SIZE];
|
||||
let end: *mut c_char = unsafe { itoa2(-123, buffer.as_mut_ptr()) };
|
||||
let result =
|
||||
unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
assert_eq!(result, "-0b1111011");
|
||||
assert_eq!(end, unsafe { buffer.as_mut_ptr().offset(10) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa8() {
|
||||
let mut buffer: [i8; UTOA8_BUFFER_SIZE] = [0; UTOA8_BUFFER_SIZE];
|
||||
|
|
|
@ -8,6 +8,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_ntoa() {
|
||||
assert_eq!(utoa2(123), "0b1111011");
|
||||
assert_eq!(itoa2(123), "0b1111011");
|
||||
assert_eq!(utoa8(0o123), "0o123");
|
||||
assert_eq!(itoa8(0o123), "0o123");
|
||||
assert_eq!(utoa10(123), "123");
|
||||
|
|
|
@ -1,13 +1,34 @@
|
|||
use std::ffi::CStr;
|
||||
|
||||
use kernaux_sys::{
|
||||
itoa10 as kernaux_itoa10, itoa16 as kernaux_itoa16, itoa8 as kernaux_itoa8,
|
||||
utoa10 as kernaux_utoa10, utoa16 as kernaux_utoa16, utoa8 as kernaux_utoa8,
|
||||
itoa10 as kernaux_itoa10, itoa16 as kernaux_itoa16,
|
||||
utoa10 as kernaux_utoa10, utoa16 as kernaux_utoa16,
|
||||
};
|
||||
use kernaux_sys::{
|
||||
ITOA10_BUFFER_SIZE, ITOA16_BUFFER_SIZE, ITOA8_BUFFER_SIZE,
|
||||
UTOA10_BUFFER_SIZE, UTOA16_BUFFER_SIZE, UTOA8_BUFFER_SIZE,
|
||||
itoa2 as kernaux_itoa2, itoa8 as kernaux_itoa8, utoa2 as kernaux_utoa2,
|
||||
utoa8 as kernaux_utoa8,
|
||||
};
|
||||
use kernaux_sys::{
|
||||
ITOA10_BUFFER_SIZE, ITOA16_BUFFER_SIZE, UTOA10_BUFFER_SIZE,
|
||||
UTOA16_BUFFER_SIZE,
|
||||
};
|
||||
use kernaux_sys::{
|
||||
ITOA2_BUFFER_SIZE, ITOA8_BUFFER_SIZE, UTOA2_BUFFER_SIZE, UTOA8_BUFFER_SIZE,
|
||||
};
|
||||
|
||||
pub fn utoa2(value: u64) -> String {
|
||||
let mut buffer: [i8; UTOA2_BUFFER_SIZE] = [0; UTOA2_BUFFER_SIZE];
|
||||
unsafe { kernaux_utoa2(value, buffer.as_mut_ptr()) };
|
||||
let result = unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
String::from(result)
|
||||
}
|
||||
|
||||
pub fn itoa2(value: i64) -> String {
|
||||
let mut buffer: [i8; ITOA2_BUFFER_SIZE] = [0; ITOA2_BUFFER_SIZE];
|
||||
unsafe { kernaux_itoa2(value, buffer.as_mut_ptr()) };
|
||||
let result = unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_str().unwrap();
|
||||
String::from(result)
|
||||
}
|
||||
|
||||
pub fn utoa8(value: u64) -> String {
|
||||
let mut buffer: [i8; UTOA8_BUFFER_SIZE] = [0; UTOA8_BUFFER_SIZE];
|
||||
|
@ -55,6 +76,34 @@ pub fn itoa16(value: i64) -> String {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_utoa2() {
|
||||
assert_eq!(utoa2(0), "0b0");
|
||||
assert_eq!(utoa2(1), "0b1");
|
||||
assert_eq!(utoa2(123), "0b1111011");
|
||||
assert_eq!(
|
||||
utoa2(u64::MAX),
|
||||
"0b1111111111111111111111111111111111111111111111111111111111111111",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_itoa2() {
|
||||
assert_eq!(itoa2(0), "0b0");
|
||||
assert_eq!(itoa2(1), "0b1");
|
||||
assert_eq!(itoa2(-1), "-0b1");
|
||||
assert_eq!(itoa2(123), "0b1111011");
|
||||
assert_eq!(itoa2(-123), "-0b1111011");
|
||||
assert_eq!(
|
||||
itoa2(i64::MAX),
|
||||
"0b111111111111111111111111111111111111111111111111111111111111111",
|
||||
);
|
||||
assert_eq!(
|
||||
itoa2(i64::MIN),
|
||||
"-0b1000000000000000000000000000000000000000000000000000000000000000",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_utoa8() {
|
||||
assert_eq!(utoa8(0), "0o0");
|
||||
|
|
10
src/ntoa.c
10
src/ntoa.c
|
@ -62,6 +62,16 @@ char *kernaux_itoa(int64_t value, char *buffer, int base, const char *const pref
|
|||
}
|
||||
}
|
||||
|
||||
char *kernaux_utoa2(uint64_t value, char *buffer)
|
||||
{
|
||||
return kernaux_utoa(value, buffer, 'b', KERNAUX_NTOA_DEFAULT_PREFIX_2);
|
||||
}
|
||||
|
||||
char *kernaux_itoa2(int64_t value, char *buffer)
|
||||
{
|
||||
return kernaux_itoa(value, buffer, 'b', KERNAUX_NTOA_DEFAULT_PREFIX_2);
|
||||
}
|
||||
|
||||
char *kernaux_utoa8(uint64_t value, char *buffer)
|
||||
{
|
||||
return kernaux_utoa(value, buffer, 'o', KERNAUX_NTOA_DEFAULT_PREFIX_8);
|
||||
|
|
|
@ -127,6 +127,65 @@ static const struct {
|
|||
{ "9ix", 36, 12345 }, { "9IX", -36, 12345 },
|
||||
};
|
||||
|
||||
static const struct {
|
||||
uint64_t value;
|
||||
const char *result;
|
||||
} utoa2_cases[] = {
|
||||
{ 0, "0" },
|
||||
{ 1, "1" },
|
||||
{ 2, "10" },
|
||||
{ 3, "11" },
|
||||
{ 4, "100" },
|
||||
{ 5, "101" },
|
||||
{ 6, "110" },
|
||||
{ 7, "111" },
|
||||
{ 8, "1000" },
|
||||
{ UINT16_MAX, "1111111111111111" },
|
||||
{ UINT16_MAX + 1, "10000000000000000" },
|
||||
{ UINT32_MAX, "11111111111111111111111111111111" },
|
||||
{ (uint64_t)UINT32_MAX + 1, "100000000000000000000000000000000" },
|
||||
{ UINT64_MAX - 6, "1111111111111111111111111111111111111111111111111111111111111001" },
|
||||
{ UINT64_MAX - 5, "1111111111111111111111111111111111111111111111111111111111111010" },
|
||||
{ UINT64_MAX - 1, "1111111111111111111111111111111111111111111111111111111111111110" },
|
||||
{ UINT64_MAX, "1111111111111111111111111111111111111111111111111111111111111111" },
|
||||
};
|
||||
|
||||
static const struct {
|
||||
int64_t value;
|
||||
const char *result;
|
||||
} itoa2_cases[] = {
|
||||
{ 0, "0" },
|
||||
{ 1, "1" },
|
||||
{ -1, "-1" },
|
||||
{ 2, "10" },
|
||||
{ -2, "-10" },
|
||||
{ 3, "11" },
|
||||
{ -3, "-11" },
|
||||
{ 4, "100" },
|
||||
{ -4, "-100" },
|
||||
{ 5, "101" },
|
||||
{ -5, "-101" },
|
||||
{ 6, "110" },
|
||||
{ -6, "-110" },
|
||||
{ 7, "111" },
|
||||
{ -7, "-111" },
|
||||
{ 8, "1000" },
|
||||
{ -8, "-1000" },
|
||||
{ UINT16_MAX, "1111111111111111" },
|
||||
{ UINT16_MAX + 1, "10000000000000000" },
|
||||
{ UINT32_MAX, "11111111111111111111111111111111" },
|
||||
{ (int64_t)UINT32_MAX + 1, "100000000000000000000000000000000" },
|
||||
{ INT64_MAX - 6, "111111111111111111111111111111111111111111111111111111111111001" },
|
||||
{ INT64_MIN + 7, "-111111111111111111111111111111111111111111111111111111111111001" },
|
||||
{ INT64_MAX - 5, "111111111111111111111111111111111111111111111111111111111111010" },
|
||||
{ INT64_MIN + 6, "-111111111111111111111111111111111111111111111111111111111111010" },
|
||||
{ INT64_MAX - 1, "111111111111111111111111111111111111111111111111111111111111110" },
|
||||
{ INT64_MIN + 2, "-111111111111111111111111111111111111111111111111111111111111110" },
|
||||
{ INT64_MAX, "111111111111111111111111111111111111111111111111111111111111111" },
|
||||
{ INT64_MIN + 1, "-111111111111111111111111111111111111111111111111111111111111111" },
|
||||
{ INT64_MIN, "-1000000000000000000000000000000000000000000000000000000000000000" },
|
||||
};
|
||||
|
||||
static const struct {
|
||||
uint64_t value;
|
||||
const char *result;
|
||||
|
@ -592,6 +651,51 @@ int main()
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
char buffer[KERNAUX_UTOA2_BUFFER_SIZE];
|
||||
|
||||
for (
|
||||
size_t index = 0;
|
||||
index < sizeof(utoa2_cases) / sizeof(utoa2_cases[0]);
|
||||
++index
|
||||
) {
|
||||
const char *const end1 =
|
||||
kernaux_utoa2(utoa2_cases[index].value, buffer);
|
||||
assert(strncmp(buffer, "0b", 2) == 0);
|
||||
assert(strcmp(&buffer[2], utoa2_cases[index].result) == 0);
|
||||
assert(end1 == str_end(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
char buffer[KERNAUX_ITOA2_BUFFER_SIZE];
|
||||
|
||||
for (
|
||||
size_t index = 0;
|
||||
index < sizeof(itoa2_cases) / sizeof(itoa2_cases[0]);
|
||||
++index
|
||||
) {
|
||||
const int64_t value = itoa2_cases[index].value;
|
||||
|
||||
const char *const end1 = kernaux_itoa2(value, buffer);
|
||||
if (value >= 0) {
|
||||
assert(strncmp(buffer, "0b", 2) == 0);
|
||||
assert(strcmp(&buffer[2], itoa2_cases[index].result) == 0);
|
||||
} else {
|
||||
assert(strncmp(buffer, "-0b", 3) == 0);
|
||||
assert(strcmp(&buffer[3], &itoa2_cases[index].result[1]) == 0);
|
||||
}
|
||||
assert(end1 == str_end(buffer));
|
||||
|
||||
if (value <= 0) continue;
|
||||
|
||||
const char *const end2 = kernaux_itoa2(-value, buffer);
|
||||
assert(strncmp(buffer, "-0b", 3) == 0);
|
||||
assert(strcmp(&buffer[3], itoa2_cases[index].result) == 0);
|
||||
assert(end2 == str_end(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
char buffer[KERNAUX_UTOA8_BUFFER_SIZE];
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue