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|
|
||||
|Natural|x10|--|Non-negative integers|
|
||||
|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|
|
||||
|Sequence|x1f|--|Variable-sized series of bytes|
|
||||
|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()`
|
||||
* `natural()`
|
||||
* `integer()`
|
||||
* `decimal(mantissa)`
|
||||
* `significant()`
|
||||
* `block(size)`
|
||||
* `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)) {
|
||||
@ -379,12 +381,70 @@ value.set(-273);
|
||||
---
|
||||
|
||||
## 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
|
||||
Stores a fixed-precision, variable-magnitude number.
|
||||
Stores a variable-magnitude rational number.
|
||||
|
||||
> Encode/decode not implemented.
|
||||
|
||||
|
@ -1,9 +1,17 @@
|
||||
fn main() {
|
||||
let a = szun::Decimal::with(32, 18.5);
|
||||
let b = szun::Decimal::with(24, 6.0);
|
||||
fn print_bytes(bytes:&Vec<u8>)
|
||||
{
|
||||
for b in bytes {
|
||||
print!("{:02x} ", *b);
|
||||
} print!("\n");
|
||||
}
|
||||
|
||||
println!("A = {} (.{})", a.get(), a.exponent());
|
||||
println!("B = {} (.{})", b.get(), b.exponent());
|
||||
fn main() {
|
||||
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");
|
||||
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());
|
||||
|
||||
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,
|
||||
Boolean,
|
||||
Natural, Integer,
|
||||
//Significant,
|
||||
Decimal, //Significant,
|
||||
Block, Sequence,
|
||||
Array, List,
|
||||
Record,
|
||||
@ -56,6 +56,14 @@ pub fn encode_data(addr:Reference) -> Vec<u8>
|
||||
tag::INTEGER => {
|
||||
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 => {
|
||||
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 => {
|
||||
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 => {
|
||||
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 significant() -> usize { unsafe { runtime::type_outer(0, tag::SIGNIFICANT) } }
|
||||
|
||||
pub fn decimal(exponent:usize) -> usize {
|
||||
pub fn decimal(mantissa:usize) -> usize {
|
||||
unsafe {
|
||||
let inner_node = runtime::type_outer(0, exponent);
|
||||
let inner_node = runtime::type_outer(0, mantissa);
|
||||
runtime::type_outer(inner_node, tag::DECIMAL)
|
||||
}
|
||||
}
|
||||
|
@ -12,24 +12,24 @@ pub struct Decimal {
|
||||
addr:Reference,
|
||||
}
|
||||
impl Decimal {
|
||||
pub fn new(exponent:usize) -> Self
|
||||
pub fn new(mantissa:usize) -> Self
|
||||
{
|
||||
Self {
|
||||
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);
|
||||
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);
|
||||
return obj;
|
||||
}
|
||||
@ -39,30 +39,30 @@ impl Decimal {
|
||||
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) };
|
||||
}
|
||||
|
||||
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 decimal = ((value - value.trunc()).abs() * (1i64 << exponent) as f64).floor() as i64;
|
||||
let data = (whole << exponent) + (decimal as i64);
|
||||
let decimal = ((value - value.trunc()).abs() * (1i64 << mantissa) as f64).floor() as i64;
|
||||
let data = (whole << mantissa) + (decimal as i64);
|
||||
self.set_raw(data);
|
||||
}
|
||||
|
||||
fn get_raw(&self) -> i64
|
||||
pub fn get_raw(&self) -> i64
|
||||
{
|
||||
unsafe {decimal_get(self.addr)}
|
||||
}
|
||||
|
||||
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();
|
||||
(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
|
||||
@ -74,22 +74,22 @@ impl Decimal {
|
||||
} else { data }
|
||||
}
|
||||
|
||||
pub fn to_base(&self, exponent:usize) -> Self
|
||||
pub fn to_base(&self, mantissa:usize) -> Self
|
||||
{
|
||||
let from_exp = self.exponent();
|
||||
let mut result = Decimal::new(exponent);
|
||||
result.set_raw(Self::rebase(from_exp, exponent, self.get_raw()));
|
||||
let from_exp = self.mantissa();
|
||||
let mut result = Decimal::new(mantissa);
|
||||
result.set_raw(Self::rebase(from_exp, mantissa, self.get_raw()));
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn exponent(&self) -> usize
|
||||
pub fn mantissa(&self) -> usize
|
||||
{
|
||||
unsafe {type_innerkey(self.addr.class)}
|
||||
}
|
||||
}
|
||||
impl Clone for Decimal {
|
||||
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 {
|
||||
@ -200,8 +200,8 @@ impl std::ops::RemAssign for Decimal {
|
||||
impl std::ops::Neg for Decimal {
|
||||
type Output = Self;
|
||||
fn neg(self) -> Self::Output {
|
||||
let exponent = unsafe {type_innerkey(self.addr.class)};
|
||||
Decimal::with_raw(exponent, -self.get_raw())
|
||||
let mantissa = unsafe {type_innerkey(self.addr.class)};
|
||||
Decimal::with_raw(mantissa, -self.get_raw())
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Decimal {
|
||||
|
Reference in New Issue
Block a user