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/);
+ });
+});