1
0
Эх сурвалжийг харах

feat: added roundFixed() & bitSetHas(), improved digitCount()

Sv443 2 сар өмнө
parent
commit
426415421d

+ 5 - 0
.changeset/eleven-hounds-lick.md

@@ -0,0 +1,5 @@
+---
+"@sv443-network/userutils": minor
+---
+
+Added parameter `withDecimals` to `digitCount()` (true by default)

+ 5 - 0
.changeset/flat-yaks-nail.md

@@ -0,0 +1,5 @@
+---
+"@sv443-network/userutils": minor
+---
+
+Added function `roundFixed()` to round a floating-point number to the given amount of decimals. Can also round to the given power of 10.

+ 5 - 0
.changeset/mighty-lamps-hug.md

@@ -0,0 +1,5 @@
+---
+"@sv443-network/userutils": minor
+---
+
+Added function `bitSetHas()` to check if a given value is present in a [bitset](https://www.geeksforgeeks.org/cpp-bitset-and-its-application/)

+ 5 - 0
.changeset/sour-candles-clean.md

@@ -0,0 +1,5 @@
+---
+"@sv443-network/userutils": patch
+---
+
+Fixed `digitCount()` not counting decimals by default

+ 2 - 0
README-summary.md

@@ -54,6 +54,8 @@ View the documentation of previous major releases:
     - [`mapRange()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#maprange) - map a number from one range to the same spot in another range
     - [`mapRange()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#maprange) - map a number from one range to the same spot in another range
     - [`randRange()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#randrange) - generate a random number between a min and max boundary
     - [`randRange()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#randrange) - generate a random number between a min and max boundary
     - [`digitCount()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#digitcount) - calculate the amount of digits in a number
     - [`digitCount()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#digitcount) - calculate the amount of digits in a number
+    - [`roundFixed()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#roundfixed) - round a floating-point number at the given amount of decimals, or to the given power of 10
+    - [`bitSetHas()`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#bitsethas) - check if a bit is set in a [bitset](https://www.geeksforgeeks.org/cpp-bitset-and-its-application/)
 - **Misc:**
 - **Misc:**
     - [`DataStore`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#datastore) - class that manages a hybrid sync & async persistent JSON database, including data migration
     - [`DataStore`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#datastore) - class that manages a hybrid sync & async persistent JSON database, including data migration
     - [`DataStoreSerializer`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#datastoreserializer) - class for importing & exporting data of multiple DataStore instances, including compression, checksumming and running migrations
     - [`DataStoreSerializer`](https://github.com/Sv443-Network/UserUtils/blob/main/docs.md#datastoreserializer) - class for importing & exporting data of multiple DataStore instances, including compression, checksumming and running migrations

+ 2 - 0
README.md

@@ -57,6 +57,8 @@ View the documentation of previous major releases:
     - [`mapRange()`](./docs.md#maprange) - map a number from one range to the same spot in another range
     - [`mapRange()`](./docs.md#maprange) - map a number from one range to the same spot in another range
     - [`randRange()`](./docs.md#randrange) - generate a random number between a min and max boundary
     - [`randRange()`](./docs.md#randrange) - generate a random number between a min and max boundary
     - [`digitCount()`](./docs.md#digitcount) - calculate the amount of digits in a number
     - [`digitCount()`](./docs.md#digitcount) - calculate the amount of digits in a number
+    - [`roundFixed()`](./docs.md#roundfixed) - round a floating-point number at the given amount of decimals, or to the given power of 10
+    - [`bitSetHas()`](./docs.md#bitsethas) - check if a bit is set in a [bitset](https://www.geeksforgeeks.org/cpp-bitset-and-its-application/)
   - [**Misc:**](./docs.md#misc)
   - [**Misc:**](./docs.md#misc)
     - [`DataStore`](./docs.md#datastore) - class that manages a hybrid sync & async persistent JSON database, including data migration
     - [`DataStore`](./docs.md#datastore) - class that manages a hybrid sync & async persistent JSON database, including data migration
     - [`DataStoreSerializer`](./docs.md#datastoreserializer) - class for importing & exporting data of multiple DataStore instances, including compression, checksumming and running migrations
     - [`DataStoreSerializer`](./docs.md#datastoreserializer) - class for importing & exporting data of multiple DataStore instances, including compression, checksumming and running migrations

+ 73 - 3
docs.md

@@ -46,6 +46,8 @@ For submitting bug reports or feature requests, please use the [GitHub issue tra
     - [`mapRange()`](#maprange) - map a number from one range to the same spot in another range
     - [`mapRange()`](#maprange) - map a number from one range to the same spot in another range
     - [`randRange()`](#randrange) - generate a random number between a min and max boundary
     - [`randRange()`](#randrange) - generate a random number between a min and max boundary
     - [`digitCount()`](#digitcount) - calculate the amount of digits in a number
     - [`digitCount()`](#digitcount) - calculate the amount of digits in a number
+    - [`roundFixed()`](#roundfixed) - round a floating-point number at the given amount of decimals, or to the given power of 10
+    - [`bitSetHas()`](#bitsethas) - check if a bit is set in a [bitset](https://www.geeksforgeeks.org/cpp-bitset-and-its-application/)
   - [**Misc:**](#misc)
   - [**Misc:**](#misc)
     - [`DataStore`](#datastore) - class that manages a hybrid sync & async persistent JSON database, including data migration
     - [`DataStore`](#datastore) - class that manages a hybrid sync & async persistent JSON database, including data migration
     - [`DataStoreSerializer`](#datastoreserializer) - class for importing & exporting data of multiple DataStore instances, including compression, checksumming and running migrations
     - [`DataStoreSerializer`](#datastoreserializer) - class for importing & exporting data of multiple DataStore instances, including compression, checksumming and running migrations
@@ -1149,12 +1151,15 @@ benchmark(true);  // Generated 100k in 461ms
 ### digitCount()
 ### digitCount()
 Signature:  
 Signature:  
 ```ts
 ```ts
-digitCount(num: number | Stringifiable): number
+digitCount(num: number | Stringifiable, withDecimals = true): number
 ```
 ```
   
   
-Calculates and returns the amount of digits in the given number.  
+Calculates and returns the amount of digits in the given number (floating point or integer).  
 If it isn't a number already, the value will be converted by being passed to `String()` and then `Number()` before the calculation.  
 If it isn't a number already, the value will be converted by being passed to `String()` and then `Number()` before the calculation.  
-Returns `NaN` if the number is invalid and `Infinity` if the number is too large to be represented as a regular number.
+  
+Returns `NaN` if the number is invalid or `Infinity` if the number is too large to be represented as a regular number.  
+  
+If `withDecimals` is set to false, the decimal point and everything after it will be ignored.  
   
   
 <details><summary><b>Example - click to view</b></summary>
 <details><summary><b>Example - click to view</b></summary>
 
 
@@ -1178,6 +1183,71 @@ digitCount(num6); // 17
 
 
 </details>
 </details>
 
 
+<br>
+
+### roundFixed()
+Signature:  
+```ts
+roundFixed(num: number, fractionDigits: number): number
+```
+  
+Rounds a number to a fixed amount of decimal places.  
+Supports negative `fractionDigits` to round to the given power of 10.  
+  
+<details><summary><b>Example - click to view</b></summary>
+
+```ts
+import { roundFixed } from "@sv443-network/userutils";
+
+roundFixed(234.567, -2); // 200
+roundFixed(234.567, -1); // 230
+roundFixed(234.567, 0);  // 235
+roundFixed(234.567, 1);  // 234.6
+roundFixed(234.567, 2);  // 234.57
+roundFixed(234.567, 3);  // 234.567
+roundFixed(234.567, 4);  // 234.567
+```
+</details>
+
+<br>
+
+### bitSetHas()
+Signature:  
+```ts
+bitSetHas<TType extends number | bigint>(bitSet: TType, checkVal: TType): boolean
+```
+  
+Checks if the `checkVal` bit is set in the given bit set.  
+The bit set and the value to check can be either a number or a bigint, but both have to be of the same type.  
+  
+<details><summary><b>Example - click to view</b></summary>
+
+```ts
+import { bitSetHas } from "@sv443-network/userutils";
+
+// the two vertically adjacent bits are tested for:
+bitSetHas(
+  0b1110,
+  0b0010,
+); // true
+
+bitSetHas(
+  0b1110,
+  0b0001,
+); // false
+
+// with TS enums (or JS maps):
+enum MyEnum {
+  A = 1, B = 2, C = 4,
+  D = 8, E = 16, F = 32,
+}
+
+const myBitSet = MyEnum.A | MyEnum.B;
+bitSetHas(myBitSet, MyEnum.B); // true
+bitSetHas(myBitSet, MyEnum.F); // false
+```
+</details>
+
 <br><br>
 <br><br>
 
 
 <!-- #region Misc -->
 <!-- #region Misc -->

+ 68 - 6
lib/math.ts

@@ -95,16 +95,78 @@ export function randRange(...args: (number | boolean | undefined)[]): number {
     return Math.floor(Math.random() * (max - min + 1)) + min;
     return Math.floor(Math.random() * (max - min + 1)) + min;
 }
 }
 
 
-/** Calculates the amount of digits in the given number - the given number or string will be passed to the `Number()` constructor. Returns NaN if the number is invalid. */
-export function digitCount(num: number | Stringifiable): number {
+/**
+ * Calculates the amount of digits in the given number - the given number or string will be passed to the `Number()` constructor.  
+ * Returns NaN if the number is invalid.  
+ * @param num The number to count the digits of
+ * @param withDecimals Whether to count the decimal places as well (defaults to true)
+ * @example ```ts
+ * digitCount();         // NaN
+ * digitCount(0);        // 1
+ * digitCount(123);      // 3
+ * digitCount(123.456);  // 6
+ * digitCount(Infinity); // Infinity
+ * ```
+ */
+export function digitCount(num: number | Stringifiable, withDecimals = true): number {
   num = Number((!["string", "number"].includes(typeof num)) ? String(num) : num);
   num = Number((!["string", "number"].includes(typeof num)) ? String(num) : num);
 
 
   if(typeof num === "number" && isNaN(num))
   if(typeof num === "number" && isNaN(num))
     return NaN;
     return NaN;
 
 
-  return num === 0
+  const [intPart, decPart] = num.toString().split(".");
+
+  const intDigits = intPart === "0"
     ? 1
     ? 1
-    : Math.floor(
-      Math.log10(Math.abs(Number(num))) + 1
-    );
+    : Math.floor(Math.log10(Math.abs(Number(intPart))) + 1);
+  const decDigits = withDecimals && decPart
+    ? decPart.length
+    : 0;
+
+  return intDigits + decDigits;
+}
+
+/**
+ * Rounds {@linkcode num} to a fixed amount of decimal places, specified by {@linkcode fractionDigits} (supports negative values to round to the nearest power of 10).
+ * @example ```ts
+ * roundFixed(234.567, -2); // 200
+ * roundFixed(234.567, -1); // 230
+ * roundFixed(234.567, 0);  // 235
+ * roundFixed(234.567, 1);  // 234.6
+ * roundFixed(234.567, 2);  // 234.57
+ * roundFixed(234.567, 3);  // 234.567
+ * ```
+ */
+export function roundFixed(num: number, fractionDigits: number): number {
+  const scale = 10 ** fractionDigits;
+  return Math.round(num * scale) / scale;
+}
+
+/**
+ * Checks if the {@linkcode bitSet} has the {@linkcode checkVal} set
+ * @example ```ts
+ * // the two vertically adjacent bits are tested for:
+ * bitSetHas(
+ *   0b1110,
+ *   0b0010,
+ * ); // true
+ * 
+ * bitSetHas(
+ *   0b1110,
+ *   0b0001,
+ * ); // false
+ * 
+ * // with TS enums (or JS maps):
+ * enum MyEnum {
+ *   A = 1, B = 2, C = 4,
+ *   D = 8, E = 16, F = 32,
+ * }
+ * 
+ * const myBitSet = MyEnum.A | MyEnum.B;
+ * bitSetHas(myBitSet, MyEnum.B); // true
+ * bitSetHas(myBitSet, MyEnum.F); // false
+ * ```
+ */
+export function bitSetHas<TType extends number | bigint>(bitSet: TType, checkVal: TType): boolean {
+  return (bitSet & checkVal) === checkVal;
 }
 }