Update README, implement encoding for Decimal.
This commit is contained in:
parent
e7781c721f
commit
8a833b41e0
70
README.md
70
README.md
@ -33,7 +33,8 @@ While the runtime provides methods for directly acquring and releasing memory, i
|
|||||||
|Boolean|x02|--|True or false|
|
|Boolean|x02|--|True or false|
|
||||||
|Natural|x10|--|Non-negative integers|
|
|Natural|x10|--|Non-negative integers|
|
||||||
|Integer|x11|--|Positive and negative whole numbers|
|
|Integer|x11|--|Positive and negative whole numbers|
|
||||||
|Significant|x13|--|Fixed-precision, variable-magnitude numbers|
|
|Decimal|x12|mantissa|Fixed-maginutide rational numbers|
|
||||||
|
|Significant|x13|--|Variable-magnitude rational numbers|
|
||||||
|Block|x1e|size|Constant-sized series of bytes|
|
|Block|x1e|size|Constant-sized series of bytes|
|
||||||
|Sequence|x1f|--|Variable-sized series of bytes|
|
|Sequence|x1f|--|Variable-sized series of bytes|
|
||||||
|Array|x22|size, type|Constant-sized, indexed collection|
|
|Array|x22|size, type|Constant-sized, indexed collection|
|
||||||
@ -49,6 +50,7 @@ Type building functions are used to generate identifiers used in the constructio
|
|||||||
* `boolean()`
|
* `boolean()`
|
||||||
* `natural()`
|
* `natural()`
|
||||||
* `integer()`
|
* `integer()`
|
||||||
|
* `decimal(mantissa)`
|
||||||
* `significant()`
|
* `significant()`
|
||||||
* `block(size)`
|
* `block(size)`
|
||||||
* `sequence()`
|
* `sequence()`
|
||||||
@ -229,7 +231,7 @@ let value = Integer::new();
|
|||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
`from(refer:Reference) -> Result<Self,()>`
|
`try_from(refer:Reference) -> Result<Self,()>`
|
||||||
|
|
||||||
```
|
```
|
||||||
match Integer::from(list.at(0)) {
|
match Integer::from(list.at(0)) {
|
||||||
@ -379,12 +381,70 @@ value.set(-273);
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Decimal
|
## Decimal
|
||||||
Stores a constant-magnitude number with whole and decimal components.
|
Stores a constant-magnitude rational number of specified mantissa size.
|
||||||
|
|
||||||
> Not implemented.
|
`new(mantissa:u8) -> Self`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`with(mantissa:u8, value:f64) -> Self`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`with_raw(mantissa:u8, value:i64) -> Self`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`get() -> f64`
|
||||||
|
|
||||||
|
Returns the contained value.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`get_raw() -> i64`
|
||||||
|
|
||||||
|
Returns the raw contained value.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`set(value:f64)`
|
||||||
|
|
||||||
|
Replaces the contained value.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`set_raw(value:i64)`
|
||||||
|
|
||||||
|
Replaces the raw contained value.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`-Neg() -> Self`
|
||||||
|
|
||||||
|
`Add+(rhs:Self) -> Self`
|
||||||
|
|
||||||
|
`AddAssign+=(rhs:Self)`
|
||||||
|
|
||||||
|
`Sub-(rhs:Self) -> Self`
|
||||||
|
|
||||||
|
`SubAssign-=(rhs:Self)`
|
||||||
|
|
||||||
|
`Mul*(rhs:Self) -> Self`
|
||||||
|
|
||||||
|
`MulAssign*=(rhs:Self)`
|
||||||
|
|
||||||
|
`Div/(rhs:Self) -> Self`
|
||||||
|
|
||||||
|
`DivAssign/=(rhs:Self)`
|
||||||
|
|
||||||
|
`Rem%(rhs:Self) -> Self`
|
||||||
|
|
||||||
|
`RemAssign%=(rhs:Self)`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Significant
|
## Significant
|
||||||
Stores a fixed-precision, variable-magnitude number.
|
Stores a variable-magnitude rational number.
|
||||||
|
|
||||||
> Encode/decode not implemented.
|
> Encode/decode not implemented.
|
||||||
|
|
||||||
|
@ -1,9 +1,17 @@
|
|||||||
fn main() {
|
fn print_bytes(bytes:&Vec<u8>)
|
||||||
let a = szun::Decimal::with(32, 18.5);
|
{
|
||||||
let b = szun::Decimal::with(24, 6.0);
|
for b in bytes {
|
||||||
|
print!("{:02x} ", *b);
|
||||||
|
} print!("\n");
|
||||||
|
}
|
||||||
|
|
||||||
println!("A = {} (.{})", a.get(), a.exponent());
|
fn main() {
|
||||||
println!("B = {} (.{})", b.get(), b.exponent());
|
let a = szun::Decimal::with(32, 128.5);
|
||||||
|
let b = szun::Decimal::with(24, 16.0);
|
||||||
|
let c = a.copy() / b.copy();
|
||||||
|
|
||||||
|
println!("A = {} (.{})", a.get(), a.mantissa());
|
||||||
|
println!("B = {} (.{})", b.get(), b.mantissa());
|
||||||
print!("\n");
|
print!("\n");
|
||||||
println!("A + B = {}", (a.copy() + b.copy()).get());
|
println!("A + B = {}", (a.copy() + b.copy()).get());
|
||||||
println!("A - B = {}", (a.copy() - b.copy()).get());
|
println!("A - B = {}", (a.copy() - b.copy()).get());
|
||||||
@ -16,4 +24,18 @@ fn main() {
|
|||||||
println!("B * A = {}", (b.copy() * a.copy()).get());
|
println!("B * A = {}", (b.copy() * a.copy()).get());
|
||||||
println!("B / A = {}", (b.copy() / a.copy()).get());
|
println!("B / A = {}", (b.copy() / a.copy()).get());
|
||||||
println!("B % A = {}", (b.copy() % a.copy()).get());
|
println!("B % A = {}", (b.copy() % a.copy()).get());
|
||||||
|
|
||||||
|
print!("\n");
|
||||||
|
let out = szun::encode(*c);
|
||||||
|
println!("c = {}", c.get());
|
||||||
|
print_bytes(&out);
|
||||||
|
match szun::decode(&out, &mut 0) {
|
||||||
|
Ok(ty) => match ty {
|
||||||
|
szun::Type::Decimal(val) => {
|
||||||
|
println!("decode = {}", val.get());
|
||||||
|
}
|
||||||
|
_ => { println!("other"); }
|
||||||
|
}
|
||||||
|
Err(_) => { println!("failed"); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ use crate::{
|
|||||||
Varying,
|
Varying,
|
||||||
Boolean,
|
Boolean,
|
||||||
Natural, Integer,
|
Natural, Integer,
|
||||||
//Significant,
|
Decimal, //Significant,
|
||||||
Block, Sequence,
|
Block, Sequence,
|
||||||
Array, List,
|
Array, List,
|
||||||
Record,
|
Record,
|
||||||
@ -56,6 +56,14 @@ pub fn encode_data(addr:Reference) -> Vec<u8>
|
|||||||
tag::INTEGER => {
|
tag::INTEGER => {
|
||||||
result.append(&mut &mut util::pack_integer(Integer::try_from(addr).unwrap().get() as i64));
|
result.append(&mut &mut util::pack_integer(Integer::try_from(addr).unwrap().get() as i64));
|
||||||
}
|
}
|
||||||
|
tag::DECIMAL => {
|
||||||
|
let mantissa = unsafe {type_innerkey(addr.class)};
|
||||||
|
let raw = Decimal::try_from(addr).unwrap().get_raw();
|
||||||
|
let whole = raw >> mantissa;
|
||||||
|
let fract = (raw as u64 & ((1u64 << mantissa) - 1)).reverse_bits() >> (u64::BITS as usize - mantissa);
|
||||||
|
result.append(&mut &mut util::pack_integer(whole));
|
||||||
|
result.append(&mut &mut util::pack_natural(fract));
|
||||||
|
}
|
||||||
tag::SIGNIFICANT => {
|
tag::SIGNIFICANT => {
|
||||||
result.append(&mut vec![0]);
|
result.append(&mut vec![0]);
|
||||||
}
|
}
|
||||||
@ -191,6 +199,14 @@ pub fn decode_data(data:&Vec<u8>, type_id:usize, index:&mut usize) -> Result<Typ
|
|||||||
tag::INTEGER => {
|
tag::INTEGER => {
|
||||||
return Ok(Type::Integer(Integer::with(unpack_integer(data, index))));
|
return Ok(Type::Integer(Integer::with(unpack_integer(data, index))));
|
||||||
}
|
}
|
||||||
|
tag::DECIMAL => {
|
||||||
|
let mantissa = unsafe {type_innerkey(type_id)};
|
||||||
|
let whole = unpack_integer(data, index);
|
||||||
|
let fract = unpack_natural(data, index).reverse_bits() >> (u64::BITS as usize - mantissa);
|
||||||
|
let raw = (whole << mantissa) | fract as i64;
|
||||||
|
|
||||||
|
return Ok(Type::Decimal(Decimal::with_raw(unsafe {type_innerkey(type_id)}, raw)));
|
||||||
|
}
|
||||||
tag::SIGNIFICANT => {
|
tag::SIGNIFICANT => {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ pub fn natural() -> usize { unsafe { runtime::type_outer(0, tag::NATURAL) } }
|
|||||||
pub fn integer() -> usize { unsafe { runtime::type_outer(0, tag::INTEGER) } }
|
pub fn integer() -> usize { unsafe { runtime::type_outer(0, tag::INTEGER) } }
|
||||||
pub fn significant() -> usize { unsafe { runtime::type_outer(0, tag::SIGNIFICANT) } }
|
pub fn significant() -> usize { unsafe { runtime::type_outer(0, tag::SIGNIFICANT) } }
|
||||||
|
|
||||||
pub fn decimal(exponent:usize) -> usize {
|
pub fn decimal(mantissa:usize) -> usize {
|
||||||
unsafe {
|
unsafe {
|
||||||
let inner_node = runtime::type_outer(0, exponent);
|
let inner_node = runtime::type_outer(0, mantissa);
|
||||||
runtime::type_outer(inner_node, tag::DECIMAL)
|
runtime::type_outer(inner_node, tag::DECIMAL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,24 +12,24 @@ pub struct Decimal {
|
|||||||
addr:Reference,
|
addr:Reference,
|
||||||
}
|
}
|
||||||
impl Decimal {
|
impl Decimal {
|
||||||
pub fn new(exponent:usize) -> Self
|
pub fn new(mantissa:usize) -> Self
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
managed:true,
|
managed:true,
|
||||||
addr:unsafe {acquire(decimal(exponent))},
|
addr:unsafe {acquire(decimal(mantissa))},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_raw(exponent:usize, data:i64) -> Self
|
pub fn with_raw(mantissa:usize, data:i64) -> Self
|
||||||
{
|
{
|
||||||
let mut obj = Self::new(exponent);
|
let mut obj = Self::new(mantissa);
|
||||||
obj.set_raw(data);
|
obj.set_raw(data);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with(exponent:usize, value:f64) -> Self
|
pub fn with(mantissa:usize, value:f64) -> Self
|
||||||
{
|
{
|
||||||
let mut obj = Self::new(exponent);
|
let mut obj = Self::new(mantissa);
|
||||||
obj.set(value);
|
obj.set(value);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@ -39,30 +39,30 @@ impl Decimal {
|
|||||||
Decimal::try_from(self.addr).unwrap()
|
Decimal::try_from(self.addr).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_raw(&mut self, data:i64)
|
pub fn set_raw(&mut self, data:i64)
|
||||||
{
|
{
|
||||||
unsafe { decimal_set(self.addr, data) };
|
unsafe { decimal_set(self.addr, data) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, value:f64)
|
pub fn set(&mut self, value:f64)
|
||||||
{
|
{
|
||||||
let exponent = unsafe {type_innerkey(self.addr.class)};
|
let mantissa = unsafe {type_innerkey(self.addr.class)};
|
||||||
let whole = value as i64;
|
let whole = value as i64;
|
||||||
let decimal = ((value - value.trunc()).abs() * (1i64 << exponent) as f64).floor() as i64;
|
let decimal = ((value - value.trunc()).abs() * (1i64 << mantissa) as f64).floor() as i64;
|
||||||
let data = (whole << exponent) + (decimal as i64);
|
let data = (whole << mantissa) + (decimal as i64);
|
||||||
self.set_raw(data);
|
self.set_raw(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_raw(&self) -> i64
|
pub fn get_raw(&self) -> i64
|
||||||
{
|
{
|
||||||
unsafe {decimal_get(self.addr)}
|
unsafe {decimal_get(self.addr)}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self) -> f64
|
pub fn get(&self) -> f64
|
||||||
{
|
{
|
||||||
let exponent = unsafe {type_innerkey(self.addr.class)};
|
let mantissa = unsafe {type_innerkey(self.addr.class)};
|
||||||
let data = self.get_raw();
|
let data = self.get_raw();
|
||||||
(data >> exponent) as f64 + ((data & ((1i64 << exponent) - 1)) as f64 / (1i64 << exponent) as f64)
|
(data >> mantissa) as f64 + ((data & ((1i64 << mantissa) - 1)) as f64 / (1i64 << mantissa) as f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rebase(to:usize, from:usize, data:i64) -> i64
|
fn rebase(to:usize, from:usize, data:i64) -> i64
|
||||||
@ -74,22 +74,22 @@ impl Decimal {
|
|||||||
} else { data }
|
} else { data }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_base(&self, exponent:usize) -> Self
|
pub fn to_base(&self, mantissa:usize) -> Self
|
||||||
{
|
{
|
||||||
let from_exp = self.exponent();
|
let from_exp = self.mantissa();
|
||||||
let mut result = Decimal::new(exponent);
|
let mut result = Decimal::new(mantissa);
|
||||||
result.set_raw(Self::rebase(from_exp, exponent, self.get_raw()));
|
result.set_raw(Self::rebase(from_exp, mantissa, self.get_raw()));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exponent(&self) -> usize
|
pub fn mantissa(&self) -> usize
|
||||||
{
|
{
|
||||||
unsafe {type_innerkey(self.addr.class)}
|
unsafe {type_innerkey(self.addr.class)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Clone for Decimal {
|
impl Clone for Decimal {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Decimal::with_raw(self.exponent(), self.get_raw())
|
Decimal::with_raw(self.mantissa(), self.get_raw())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl std::ops::Add for Decimal {
|
impl std::ops::Add for Decimal {
|
||||||
@ -200,8 +200,8 @@ impl std::ops::RemAssign for Decimal {
|
|||||||
impl std::ops::Neg for Decimal {
|
impl std::ops::Neg for Decimal {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn neg(self) -> Self::Output {
|
fn neg(self) -> Self::Output {
|
||||||
let exponent = unsafe {type_innerkey(self.addr.class)};
|
let mantissa = unsafe {type_innerkey(self.addr.class)};
|
||||||
Decimal::with_raw(exponent, -self.get_raw())
|
Decimal::with_raw(mantissa, -self.get_raw())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl std::ops::Deref for Decimal {
|
impl std::ops::Deref for Decimal {
|
||||||
|
Reference in New Issue
Block a user