Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ These changes improve throughput and reduce memory pressure when working with la
- [formatList](#formatlist) - Formats an array of strings into a human-readable list with proper commas and "and".
- [formatToOctal](#formattotoctal) - Converts a decimal number to octal, optional "0o" prefix.
- [formatTemperature](#formattemperature) - Converts temperatures between Celsius, Fahrenheit, and Kelvin.
- [formatToHexadecimal](#formattohexadecimal) - Converts temperatures between Celsius, Fahrenheit, and Kelvin.

- [formatToDecimal](#formattodecimal) - Converts base-2/8/16 strings to decimal.

## 📋 API Reference
Expand Down Expand Up @@ -1530,6 +1532,46 @@ 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="formattohexadecimal"></a>formatToHexadecimal(num, options)
Converts a decimal number into its hexadecimal (base-16) string representation.</br>
Supports optional prefix "0x" and lowercase formatting.</br>
Handles negative numbers by adding a - sign before the output.</br>
Throws a TypeError if the input is not a valid number.</br>

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

formatToHexadecimal(10); // "A"
formatToHexadecimal(15); // "F"
formatToHexadecimal(255); // "FF"
formatToHexadecimal(4095); // "FFF"

// Negative numbers
formatToHexadecimal(-255); // "-FF"

// With prefix
formatToHexadecimal(255, { prefix: true }); // "0xFF"
formatToHexadecimal(-255, { prefix: true }); // "-0xFF"

// Lowercase output
formatToHexadecimal(255, { lowercase: true }); // "ff"

// Prefix + lowercase
formatToHexadecimal(255, { prefix: true, lowercase: true }); // "0xff"

// Invalid cases
formatToHexadecimal('255'); // TypeError
formatToHexadecimal(null); // TypeError
formatToHexadecimal(NaN); // TypeError
```

| Parameter | Type | Default | Description |
| ----------------- | ------------------- | -------- | --------------------------------------------------------- |
| num | number | required | The decimal number to convert to hexadecimal. |
| options | object *(optional)* | `{}` | Formatting options. |
| options.prefix | boolean | `false` | Adds `"0x"` before the result (or `"-0x"` for negatives). |
| options.lowercase | boolean | `false` | Outputs letters in lowercase (`"ff"` instead of `"FF"`). |

#### <a id="formattodecimal"></a>`formatToDecimal(value, options)`

Converts a binary, octal, or hexadecimal string into its decimal (base‑10) number. Supports optional standard prefixes and trims whitespace. Hex accepts uppercase and lowercase.
Expand Down
43 changes: 43 additions & 0 deletions src/formatting/hexadecimal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Converts a decimal number to its hexadecimal (base-16) representation.
*
* @param {number} num - The decimal number to convert.
* @param {object} [options] - Optional formatting options.
* @param {boolean} [options.prefix=false] - Whether to add "0x" before the result.
* @param {boolean} [options.lowercase=false] - Whether to return hexadecimal in lowercase.
* @returns {string} The hexadecimal representation of the number.
* @throws {TypeError} If the input is not a valid number.
*/
export function formatToHexadecimal(
num: number,
options?: { prefix?: boolean; lowercase?: boolean }
): string {
if (typeof num !== 'number' || isNaN(num)) {
throw new TypeError('Input must be a valid number');
}

const { prefix = false, lowercase = false } = options || {};

// Convert number to hexadecimal (absolute value first to handle negatives)
let hex = Math.abs(num).toString(16).toUpperCase();

if (lowercase) {
hex = hex.toLowerCase();
}

// Add negative sign if original number was negative
if (num < 0) {
hex = '-' + hex;
}

// Add prefix (0x or -0x) if enabled
if (prefix) {
if (hex.startsWith('-')) {
hex = '-0x' + hex.slice(1);
} else {
hex = '0x' + hex;
}
}

return hex;
}
5 changes: 4 additions & 1 deletion src/formatting/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export { formatOrdinal } from './ordinal';
export { formatList } from './listToString';
export { formatToOctal } from './octal';
export { formatTemperature } from './temperature';
export { formatToHexadecimal } from './hexadecimal';
export { formatToDecimal } from './decimal';

import { capitalize } from './capitalize';
Expand All @@ -24,6 +25,7 @@ import { formatOrdinal } from './ordinal';
import { formatList } from './listToString';
import { formatToOctal } from './octal';
import { formatTemperature } from './temperature';
import { formatToHexadecimal } from './hexadecimal';
import { formatToDecimal } from './decimal';

export const formatting = {
Expand All @@ -38,6 +40,7 @@ export const formatting = {
formatOrdinal,
formatList,
formatTemperature,
formatToHexadecimal,
formatToOctal,
formatToDecimal,
formatToOctal
};
39 changes: 39 additions & 0 deletions src/tests/formatting/hexadecimal.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { describe, it } from 'node:test';
import assert from 'node:assert';
import { formatToHexadecimal } from '../../formatting/hexadecimal';

describe('formatToHexadecimal', () => {
it('converts decimal to hexadecimal (uppercase by default)', () => {
assert.strictEqual(formatToHexadecimal(10), 'A');
assert.strictEqual(formatToHexadecimal(15), 'F');
assert.strictEqual(formatToHexadecimal(255), 'FF');
assert.strictEqual(formatToHexadecimal(4095), 'FFF');
});

it('handles negative numbers', () => {
assert.strictEqual(formatToHexadecimal(-255), '-FF');
assert.strictEqual(formatToHexadecimal(-4095), '-FFF');
});

it('supports prefix option (0x)', () => {
assert.strictEqual(formatToHexadecimal(255, { prefix: true }), '0xFF');
assert.strictEqual(formatToHexadecimal(-255, { prefix: true }), '-0xFF');
});

it('supports lowercase option', () => {
assert.strictEqual(formatToHexadecimal(255, { lowercase: true }), 'ff');
assert.strictEqual(formatToHexadecimal(4095, { lowercase: true }), 'fff');
});

it('supports both prefix and lowercase together', () => {
assert.strictEqual(formatToHexadecimal(255, { prefix: true, lowercase: true }), '0xff');
assert.strictEqual(formatToHexadecimal(-255, { prefix: true, lowercase: true }), '-0xff');
});

it('throws an error for non-numeric inputs', () => {
assert.throws(() => formatToHexadecimal('123' as any), /Input must be a valid number/);
assert.throws(() => formatToHexadecimal(null as any), /Input must be a valid number/);
assert.throws(() => formatToHexadecimal(undefined as any), /Input must be a valid number/);
assert.throws(() => formatToHexadecimal(NaN as any), /Input must be a valid number/);
});
});