@@ -1307,10 +1307,10 @@ impl<T: ArrayValue> Array<T> {
1307
1307
1308
1308
impl Value {
1309
1309
/// Encode the `bits` of the value
1310
- pub fn bits ( & self , env : & Uiua ) -> UiuaResult < Value > {
1310
+ pub fn bits ( & self , count : Option < usize > , env : & Uiua ) -> UiuaResult < Value > {
1311
1311
match self {
1312
- Value :: Byte ( n) => n. bits ( env) ,
1313
- Value :: Num ( n) => n. bits ( env) ,
1312
+ Value :: Byte ( n) => n. bits ( count , env) ,
1313
+ Value :: Num ( n) => n. bits ( count , env) ,
1314
1314
_ => Err ( env. error ( "Argument to bits must be an array of natural numbers" ) ) ,
1315
1315
}
1316
1316
}
@@ -1328,19 +1328,24 @@ impl Value {
1328
1328
. pop ( )
1329
1329
. unwrap_or ( 0 ) ;
1330
1330
match self {
1331
- Value :: Byte ( n) => n. bits_impl ( min_bits_len, env) ,
1332
- Value :: Num ( n) => n. bits_impl ( min_bits_len, env) ,
1331
+ Value :: Byte ( n) => n. bits_impl ( min_bits_len, None , env) ,
1332
+ Value :: Num ( n) => n. bits_impl ( min_bits_len, None , env) ,
1333
1333
_ => Err ( env. error ( "Argument to undo un bits must be an array of integers" ) ) ,
1334
1334
}
1335
1335
}
1336
1336
}
1337
1337
1338
1338
impl < T : RealArrayValue > Array < T > {
1339
1339
/// Encode the `bits` of the array
1340
- pub fn bits ( & self , env : & Uiua ) -> UiuaResult < Value > {
1341
- self . bits_impl ( 0 , env)
1340
+ pub fn bits ( & self , count : Option < usize > , env : & Uiua ) -> UiuaResult < Value > {
1341
+ self . bits_impl ( 0 , count , env)
1342
1342
}
1343
- fn bits_impl ( & self , min_bits_len : usize , env : & Uiua ) -> UiuaResult < Value > {
1343
+ fn bits_impl (
1344
+ & self ,
1345
+ min_bits_len : usize ,
1346
+ count : Option < usize > ,
1347
+ env : & Uiua ,
1348
+ ) -> UiuaResult < Value > {
1344
1349
let mut nats = Vec :: with_capacity ( self . data . len ( ) ) ;
1345
1350
let mut negatives = Vec :: with_capacity ( self . data . len ( ) ) ;
1346
1351
let mut any_neg = false ;
@@ -1357,33 +1362,41 @@ impl<T: RealArrayValue> Array<T> {
1357
1362
Primitive :: Bits . format( )
1358
1363
) ) ) ;
1359
1364
}
1360
- nats. push ( n. abs ( ) . round ( ) as u128 ) ;
1365
+ let mut nat = n. abs ( ) . round ( ) as u128 ;
1366
+ if let Some ( count) = count {
1367
+ nat &= ( 1 << count) - 1 ;
1368
+ }
1369
+ nats. push ( nat) ;
1361
1370
negatives. push ( n < 0.0 ) ;
1362
1371
any_neg |= n < 0.0 ;
1363
1372
}
1364
- let mut max = if let Some ( max ) = nats . iter ( ) . max ( ) {
1365
- * max
1373
+ let bit_count = if let Some ( count ) = count {
1374
+ count
1366
1375
} else {
1367
- let mut shape = self . shape . clone ( ) ;
1368
- shape. push ( 0 ) ;
1369
- return Ok ( Array :: < u8 > :: new ( shape, CowSlice :: new ( ) ) . into ( ) ) ;
1376
+ let mut max = if let Some ( max) = nats. iter ( ) . max ( ) {
1377
+ * max
1378
+ } else {
1379
+ let mut shape = self . shape . clone ( ) ;
1380
+ shape. push ( 0 ) ;
1381
+ return Ok ( Array :: < u8 > :: new ( shape, CowSlice :: new ( ) ) . into ( ) ) ;
1382
+ } ;
1383
+ let mut max_bits = 0 ;
1384
+ while max != 0 {
1385
+ max_bits += 1 ;
1386
+ max >>= 1 ;
1387
+ }
1388
+ max_bits. max ( min_bits_len)
1370
1389
} ;
1371
- let mut max_bits = 0 ;
1372
- while max != 0 {
1373
- max_bits += 1 ;
1374
- max >>= 1 ;
1375
- }
1376
- max_bits = max_bits. max ( min_bits_len) ;
1377
1390
let mut shape = self . shape . clone ( ) ;
1378
- shape. push ( max_bits ) ;
1391
+ shape. push ( bit_count ) ;
1379
1392
let val: Value = if any_neg {
1380
1393
// If any number is negative, make a f64 array
1381
- let mut new_data = eco_vec ! [ 0.0 ; self . data. len( ) * max_bits ] ;
1394
+ let mut new_data = eco_vec ! [ 0.0 ; self . data. len( ) * bit_count ] ;
1382
1395
let new_data_slice = new_data. make_mut ( ) ;
1383
1396
// LSB first
1384
1397
for ( i, ( n, is_neg) ) in nats. into_iter ( ) . zip ( negatives) . enumerate ( ) {
1385
- for j in 0 ..max_bits {
1386
- let index = i * max_bits + j;
1398
+ for j in 0 ..bit_count {
1399
+ let index = i * bit_count + j;
1387
1400
new_data_slice[ index] = u8:: from ( n & ( 1 << j) != 0 ) as f64 ;
1388
1401
if is_neg {
1389
1402
new_data_slice[ index] = -new_data_slice[ index] ;
@@ -1393,12 +1406,12 @@ impl<T: RealArrayValue> Array<T> {
1393
1406
Array :: new ( shape, new_data) . into ( )
1394
1407
} else {
1395
1408
// If all numbers are natural, make a u8 array
1396
- let mut new_data = eco_vec ! [ 0 ; self . data. len( ) * max_bits ] ;
1409
+ let mut new_data = eco_vec ! [ 0 ; self . data. len( ) * bit_count ] ;
1397
1410
let new_data_slice = new_data. make_mut ( ) ;
1398
1411
// LSB first
1399
1412
for ( i, n) in nats. into_iter ( ) . enumerate ( ) {
1400
- for j in 0 ..max_bits {
1401
- let index = i * max_bits + j;
1413
+ for j in 0 ..bit_count {
1414
+ let index = i * bit_count + j;
1402
1415
new_data_slice[ index] = u8:: from ( n & ( 1 << j) != 0 ) ;
1403
1416
}
1404
1417
}
0 commit comments