Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ These changes improve throughput and reduce memory pressure when working with la
- [formatOrdinal](#formatordinal) - Converts a number into its ordinal string representation (e.g., 1 → "1st", 2 → "2nd").
- [formatList](#formatlist) - Formats an array of strings into a human-readable list with proper commas and "and".
- [formatTemperature](#formattemperature) - Converts temperatures between Celsius, Fahrenheit, and Kelvin.
- [formatScientific](#formatscientific) - Converts a number into scientific notation (e.g., 12345 → "1.23e+4").</br>

## 📋 API Reference

Expand Down Expand Up @@ -1484,6 +1485,35 @@ Notes:
- Kelvin values are rendered without the degree symbol (e.g., "298.15K").
- An error is thrown for invalid conversions or non-numeric input values.

#### <a id="formatscientific"></a>formatScientific(num, options)
Converts a number into scientific notation (e.g., 12345 → "1.23e+4").</br>
Supports custom precision and uppercase "E" formatting.</br>
Handles negative numbers correctly.</br>
Throws TypeError if input is not a valid number.</br>

```javascript
import { formatScientific } from 'stringzy';

formatScientific(12345); // "1.23e+4"
formatScientific(0.000123); // "1.23e-4"
formatScientific(-98765); // "-9.88e+4"

formatScientific(1000000, { precision: 4 }); // "1.0000e+6"
formatScientific(98765, { uppercase: true }); // "9.88E+4"
formatScientific(12345, { precision: 5, uppercase: true }); // "1.23450E+4"

// Invalid cases
formatScientific('12345'); // TypeError
formatScientific(null); // TypeError
```
| Parameter | Type | Default | Description |
| ----------------- | ------- | -------- | --------------------------------------------- |
| num | number | required | The number to convert to scientific notation. |
| options | object | optional | Formatting settings. |
| options.precision | number | 2 | Digits after decimal point. |
| options.uppercase | boolean | false | Uses "E" instead of "e". |


## 🔧 Usage Patterns

### Individual Function Imports
Expand Down
5 changes: 4 additions & 1 deletion src/formatting/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { formatFileSize } from './fileSize';
export { formatOrdinal } from './ordinal';
export { formatList } from './listToString';
export { formatTemperature } from './temperature';
export { formatScientific } from './scientific';

import { capitalize } from './capitalize';
import { formatNumber } from './number';
Expand All @@ -21,6 +22,7 @@ import { formatFileSize } from './fileSize';
import { formatOrdinal } from './ordinal';
import { formatList } from './listToString';
import { formatTemperature } from './temperature';
import { formatScientific } from './scientific';

export const formatting = {
capitalize,
Expand All @@ -33,5 +35,6 @@ export const formatting = {
formatFileSize,
formatOrdinal,
formatList,
formatTemperature
formatTemperature,
formatScientific
};
28 changes: 28 additions & 0 deletions src/formatting/scientific.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Converts a number to scientific (exponential) notation.
*
* @param {number} num - The number to convert.
* @param {object} [options] - Optional formatting settings.
* @param {number} [options.precision=2] - Number of digits after the decimal point.
* @param {boolean} [options.uppercase=false] - Whether to use uppercase "E" in the notation.
* @returns {string} Scientific notation of the number.
* @throws {TypeError} If input is not a valid number.
*/
export function formatScientific(
num: number,
options?: { precision?: number; uppercase?: boolean }
): string {
if (typeof num !== 'number' || isNaN(num)) {
throw new TypeError('Input must be a valid number');
}

const { precision = 2, uppercase = false } = options || {};

let scientific = num.toExponential(precision);

if (uppercase) {
scientific = scientific.replace('e', 'E');
}

return scientific;
}
36 changes: 36 additions & 0 deletions src/tests/formatting/scientific.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { describe, it } from 'node:test';
import assert from 'node:assert';
import { formatScientific } from '../../formatting/scientific';

describe('formatScientific', () => {
it('converts numbers to scientific notation with default precision (2)', () => {
assert.strictEqual(formatScientific(12345), '1.23e+4');
assert.strictEqual(formatScientific(0.000123), '1.23e-4');
});

it('handles negative numbers correctly', () => {
assert.strictEqual(formatScientific(-12345), '-1.23e+4');
assert.strictEqual(formatScientific(-0.000987), '-9.87e-4');
});

it('applies custom precision', () => {
assert.strictEqual(formatScientific(1000000, { precision: 4 }), '1.0000e+6');
assert.strictEqual(formatScientific(98765, { precision: 3 }), '9.877e+4');
});

it('uses uppercase E when specified', () => {
assert.strictEqual(formatScientific(98765, { uppercase: true }), '9.88E+4');
assert.strictEqual(formatScientific(0.000123, { uppercase: true }), '1.23E-4');
});

it('combines precision and uppercase options', () => {
assert.strictEqual(formatScientific(12345, { precision: 5, uppercase: true }), '1.23450E+4');
});

it('throws an error for invalid inputs', () => {
assert.throws(() => formatScientific('12345' as any), /Input must be a valid number/);
assert.throws(() => formatScientific(null as any), /Input must be a valid number/);
assert.throws(() => formatScientific(undefined as any), /Input must be a valid number/);
assert.throws(() => formatScientific(NaN as any), /Input must be a valid number/);
});
});