diff --git a/README.md b/README.md index 8b586bd..59e4ab6 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ These changes improve throughput and reduce memory pressure when working with la - [formatCreditCard](#formatcreditcard) - Formats a credit card number by grouping digits into readable parts. - [formatToOctal](#formattotoctal) - Converts a decimal number to octal, optional "0o" prefix. - [formatTemperature](#formattemperature) - Converts temperatures between Celsius, Fahrenheit, and Kelvin. +- [formatScientific](#formatscientific) - Converts a number into scientific notation (e.g., 12345 → "1.23e+4").
- [formatToBinary](#formattobinary) - Converts a decimal integer to a binary string with optional bit grouping. - [formatToHexadecimal](#formattohexadecimal) - Converts temperatures between Celsius, Fahrenheit, and Kelvin. - [formatToDecimal](#formattodecimal) - Converts base-2/8/16 strings to decimal. @@ -1554,6 +1555,34 @@ 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. +#### formatScientific(num, options) +Converts a number into scientific notation (e.g., 12345 → "1.23e+4").
+Supports custom precision and uppercase "E" formatting.
+Handles negative numbers correctly.
+Throws TypeError if input is not a valid number.
+ +```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". | + #### `formatToBinary(num, options)` Converts a decimal integer to its binary (base-2) string representation with optional grouping from the least significant bit for readability. Supports negative numbers. diff --git a/src/formatting/index.ts b/src/formatting/index.ts index 0fd62bc..3416937 100644 --- a/src/formatting/index.ts +++ b/src/formatting/index.ts @@ -11,6 +11,7 @@ export { formatList } from './listToString'; export { formatCreditCard } from './creditCard'; export { formatToOctal } from './octal'; export { formatTemperature } from './temperature'; +export { formatScientific } from './scientific'; export { formatToBinary } from './binary'; export { formatToHexadecimal } from './hexadecimal'; export { formatToDecimal } from './decimal'; @@ -28,6 +29,7 @@ import { formatList } from './listToString'; import { formatCreditCard } from './creditCard'; import { formatToOctal } from './octal'; import { formatTemperature } from './temperature'; +import { formatScientific } from './scientific'; import { formatToBinary } from './binary'; import { formatToHexadecimal } from './hexadecimal'; import { formatToDecimal } from './decimal'; @@ -43,8 +45,9 @@ export const formatting = { formatFileSize, formatOrdinal, formatList, - formatCreditCard, formatTemperature, + formatScientific, + formatCreditCard, formatToBinary, formatToHexadecimal, formatToOctal, diff --git a/src/formatting/scientific.ts b/src/formatting/scientific.ts new file mode 100644 index 0000000..b673588 --- /dev/null +++ b/src/formatting/scientific.ts @@ -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; +} diff --git a/src/tests/formatting/scientific.test.ts b/src/tests/formatting/scientific.test.ts new file mode 100644 index 0000000..2c769da --- /dev/null +++ b/src/tests/formatting/scientific.test.ts @@ -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/); + }); +});