Significant figures (sig figs) are the digits in a number that carry meaning contributing to its measurement resolution. In scientific and engineering contexts, they indicate the precision of a measured or calculated value. Properly reporting significant figures is crucial for conveying the accuracy of data.
Rules for Determining Significant Figures:
Non-zero digits: All non-zero digits are always significant. (e.g., 123 has 3 sig figs).
Zeros between non-zero digits: Zeros between two non-zero digits are always significant. (e.g., 1007 has 4 sig figs).
Leading zeros: Zeros to the left of the first non-zero digit are never significant. They are placeholders. (e.g., 0.0052 has 2 sig figs).
Trailing zeros:
Trailing zeros in a number with a decimal point are significant. (e.g., 12.30 has 4 sig figs; 7.000 has 4 sig figs).
Trailing zeros in a number without a decimal point are ambiguous. They may or may not be significant. To avoid ambiguity, scientific notation is preferred. (e.g., 5000 could have 1, 2, 3, or 4 sig figs. 5.0 x 10³ has 2 sig figs; 5.00 x 10³ has 3 sig figs).
Rules for Calculations:
When performing calculations, the result should be rounded to reflect the precision of the least precise measurement involved.
Addition and Subtraction: The result should have the same number of decimal places as the number with the fewest decimal places.
Example: 12.345 (3 decimal places)
+ 2.1 (1 decimal place)
——-
14.445 -> Rounded to 14.4 (1 decimal place)
Multiplication and Division: The result should have the same number of significant figures as the number with the fewest significant figures.
Example: 12.3 (3 sig figs)
x 4.567 (4 sig figs)
——-
56.1741 -> Rounded to 56.2 (3 sig figs)
This calculator helps you determine the number of significant figures in a given number and, when provided with a second number and operation type, demonstrates how to apply the rules of significant figures in calculations.
function countSigFigs(numStr) {
numStr = numStr.trim();
if (numStr === "") return 0;
// Handle scientific notation
if (numStr.toLowerCase().includes('e')) {
var parts = numStr.toLowerCase().split('e');
numStr = parts[0];
}
// Remove signs and leading/trailing zeros for easier processing initially
var processedStr = numStr.replace(/^-/, ").replace(/^\+/, ");
var decimalPointIndex = processedStr.indexOf('.');
if (processedStr === "0") return 0;
if (/^0+$/.test(processedStr.replace('.', "))) return 0; // All zeros
var sigFigs = 0;
var significantDigitFound = false;
for (var i = 0; i decimalPointIndex) { // Trailing zero AFTER decimal
sigFigs++;
} else if (decimalPointIndex !== -1 && i 1 sig fig. 500.0 -> 4 sig figs. 500 -> ambiguous.
// Let's count them if they are NOT leading zeros and we have already found a significant digit.
sigFigs++;
}
}
}
}
// Refined logic for trailing zeros in integers
if (decimalPointIndex === -1 && processedStr.length > 1) {
var trailingZeros = 0;
for(var i = processedStr.length – 1; i >= 0; i–) {
if (processedStr[i] === '0') {
trailingZeros++;
} else {
break;
}
}
// If there are trailing zeros and the number itself is not just zeros,
// and we have already counted some non-zero digits, these trailing zeros are ambiguous.
// A common convention is to count them only if explicitly indicated (like scientific notation or decimal).
// For simplicity, we will NOT count ambiguous trailing zeros in integers without a decimal point.
// Example: "500" -> 1 sig fig (only '5'). "5000" -> 1 sig fig (only '5').
// If the intention was 3 sig figs for "500", it should be "5.00 x 10^2".
// So, if no decimal, and we only found non-zero digits initially, and then zeros,
// we need to revert the count of those trailing zeros.
var tempSigFigs = 0;
var tempFoundSig = false;
for(var i = 0; i Should be 2 sig figs. Our loop counts '7' and '8'. '0.00' are skipped. Correct.
// Edge case: "5000" -> If we interpret as 1 sig fig, our logic needs to ensure it.
// If number is "5000", processedStr="5000″. sigFigs becomes 1 for '5'. Then it loops '0','0′,'0′.
// decimalPointIndex is -1. The refined integer logic will correct it.
// Final check for cases like "0", "0.0", etc.
if (processedStr.replace('.', ") === " || /^[0.]+$/.test(processedStr)) {
return 0;
}
// Re-verify trailing zeros in decimal numbers
if (decimalPointIndex !== -1) {
var numTrailingZeros = 0;
for(var i = processedStr.length – 1; i >= 0; i–) {
if (processedStr[i] === '0') {
numTrailingZeros++;
} else {
break;
}
}
// If the last non-zero digit is before the decimal, and we have trailing zeros after it, they are significant.
// E.g., "12.300" -> 5 sig figs.
// The initial loop might have overcounted if we simply incremented for all zeros after finding a non-zero.
// Let's re-evaluate based on rules.
var currentSigFigs = 0;
var foundNonZero = false;
for(var i = 0; i 0 && !/^[0.]+$/.test(processedStr)) {
// This case should ideally not happen with correct logic, but as a failsafe
// if a non-zero number somehow resulted in 0 sig figs.
// Example: input "0", processedStr="0″, returns 0. Correct.
// Example: input "0.0", processedStr="0.0″, returns 0. Correct.
// Example: input "5", processedStr="5″, returns 1. Correct.
// Example: input "50", processedStr="50″, decimalPointIndex=-1. tempSigFigs=1. sigFigs=1. Correct.
// Example: input "50.", processedStr="50.", decimalPointIndex=2. currentSigFigs=1 for '5', then '0' after '5' is counted. sigFigs=2. Correct.
// Example: input "0.5", processedStr="0.5″, decimalPointIndex=1. foundNonZero becomes true at '5'. '0' before is ignored. sigFigs=1. Correct.
}
return sigFigs;
}
function countDecimalPlaces(numStr) {
numStr = numStr.trim();
var decimalPointIndex = numStr.indexOf('.');
if (decimalPointIndex === -1) {
return 0;
}
// Count digits after the decimal point
var count = 0;
for (var i = decimalPointIndex + 1; i 123. toExponential(2) = 1.23e+2 -> 123.
// Example: 12345, sig figs = 3 -> 12300. toExponential(2) = 1.23e+4 -> 12300.
// Let's refine output to respect decimal places for addition/subtraction and sig figs for mult/div.
// Convert to string for easier manipulation
var numString = roundedNum.toString();
// Handle potential 'e' notation from toExponential
if (numString.toLowerCase().includes('e')) {
// Parse scientific notation if needed for precise decimal place control
var parts = numString.toLowerCase().split('e');
var mantissa = parseFloat(parts[0]);
var exp = parseInt(parts[1]);
var adjustedMantissa = mantissa;
var numDecimalPlacesInMantissa = 0;
if (adjustedMantissa.toString().includes('.')) {
numDecimalPlacesInMantissa = adjustedMantissa.toString().split('.')[1].length;
}
// Adjust mantissa based on exponent to get the correct decimal representation
// This is complex to get perfectly right for all cases without a dedicated BigNumber library.
// For simplicity here, we'll rely on a reasonable string conversion after rounding.
// If the number of significant figures requires more digits than currently shown,
// or fewer, we need to adjust.
// A simpler approach: use toPrecision for number of sig figs.
return num.toPrecision(sigFigs);
} else {
// If not in scientific notation, it's likely already in a good format.
// Ensure it has the correct number of sig figs if toPrecision was not used.
// The toPrecision method handles this best.
return num.toPrecision(sigFigs);
}
}
function calculateSigFigs() {
var numberInput = document.getElementById("numberInput").value;
var operationType = document.getElementById("operationType").value;
var numberInput2 = document.getElementById("numberInput2") ? document.getElementById("numberInput2").value : "";
var resultDiv = document.getElementById("result");
resultDiv.style.display = "block";
if (!numberInput || numberInput.trim() === "") {
resultDiv.innerHTML = "Please enter a number.";
return;
}
var num1SigFigs = countSigFigs(numberInput);
var resultHTML = `Number 1 (${numberInput}) has ${num1SigFigs} significant figures.`;
if (operationType === "none") {
resultDiv.innerHTML = resultHTML;
} else if (operationType === "add_subtract") {
if (!numberInput2 || numberInput2.trim() === "") {
resultDiv.innerHTML = "Please enter the second number for addition/subtraction.";
return;
}
var num1DecimalPlaces = countDecimalPlaces(numberInput);
var num2DecimalPlaces = countDecimalPlaces(numberInput2);
var precision = Math.min(num1DecimalPlaces, num2DecimalPlaces);
// Perform the addition/subtraction
var num1 = parseFloat(numberInput);
var num2 = parseFloat(numberInput2);
if (isNaN(num1) || isNaN(num2)) {
resultDiv.innerHTML = "Invalid number entered.";
return;
}
var sum = num1 + num2;
var roundedSum = sum.toFixed(precision); // Round to the minimum number of decimal places
// Count sig figs of the rounded result
var finalSigFigs = countSigFigs(roundedSum);
resultHTML += `Operation: Addition/Subtraction`;
resultHTML += `Number 2 (${numberInput2}) has ${num2DecimalPlaces} decimal place(s).`;
resultHTML += `Result should have ${precision} decimal place(s).`;
resultHTML += `Calculated sum: ${sum}`;
resultHTML += `Rounded sum: ${roundedSum} (has ${finalSigFigs} significant figures).`;
resultDiv.innerHTML = resultHTML;
} else if (operationType === "multiply_divide") {
if (!numberInput2 || numberInput2.trim() === "") {
resultDiv.innerHTML = "Please enter the second number for multiplication/division.";
return;
}
var num1SigFigs = countSigFigs(numberInput);
var num2SigFigs = countSigFigs(numberInput2);
var precision = Math.min(num1SigFigs, num2SigFigs);
// Perform the multiplication/division
var num1 = parseFloat(numberInput);
var num2 = parseFloat(numberInput2);
if (isNaN(num1) || isNaN(num2) || num2 === 0) {
resultDiv.innerHTML = "Invalid number or division by zero.";
return;
}
var product;
if (operationType === "multiply_divide") { // Assuming this block is for both mult and div
product = num1 * num2;
}
// Round to the minimum number of significant figures
var roundedProduct = product.toPrecision(precision);
// Count sig figs of the rounded result (should match 'precision')
var finalSigFigs = countSigFigs(roundedProduct);
resultHTML += `Operation: Multiplication/Division`;
resultHTML += `Number 2 (${numberInput2}) has ${num2SigFigs} significant figures.`;
resultHTML += `Result should have ${precision} significant figure(s).`;
resultHTML += `Calculated product: ${product}`;
resultHTML += `Rounded product: ${roundedProduct} (has ${finalSigFigs} significant figures).`;
resultDiv.innerHTML = resultHTML;
}
}
document.getElementById("operationType").addEventListener("change", function() {
var secondaryInputs = document.getElementById("secondaryInputs");
if (this.value === "none") {
secondaryInputs.style.display = "none";
} else {
secondaryInputs.style.display = "block";
}
});