|
Internals: REAL and String Data Types |
The Sheerpower REAL data type is not like the typical floating-point numbers used in other programming languages. Those languages rely on approximate binary representations that introduce subtle rounding errors. Sheerpower instead uses an exact decimal internal format, eliminating binary floating-point errors for decimal fractions and removing the need for defensive programming and epsilon comparisons.
Sheerpower stores every REAL number as two 64-bit signed integers:
This separation allows Sheerpower to maintain complete decimal accuracy with up to 18 digits before and 16 digits after the decimal point, deterministically.
In standard floating-point math, "magnitude mismatch" errors occur when numbers of vastly different scales are mixed. For example, adding a micro-transaction to a national balance sheet might result in the smaller value simply disappearing due to the limitations of binary representation—technically known as loss of significance (absorption). By storing the integer and fractional portions separately, Sheerpower REALs prevent magnitude mismatch. You can safely add 1 quintillion and 0.000000000000123 without losing a single digit of precision.
The illustration below shows how a REAL value is stored:
13
5990000000000000
Here's a classic example of floating-point failure in other languages:
In C, JavaScript, Python, or Java, this returns:
But in Sheerpower, the output is:
Sheerpower gives you exact representation up to 16 fractional decimal places. Anything beyond that uses half-to-even rounding—no "close enough" comparisons, no fuzzy tolerances.
| Operation | Sheerpower REAL | Java BigDecimal | Python Decimal | vs Java | vs Python |
|---|---|---|---|---|---|
| Addition | 3-85 cycles | 150-250 cycles | 200-400 cycles | 50-80× | 65-130× |
| Subtraction | 3-85 cycles | 150-250 cycles | 200-400 cycles | 50-80× | 65-130× |
| Multiplication | 150-200 cycles | 400-900 cycles | 800-1500 cycles | 2.5-6× | 4-10× |
| Division | 300-500 cycles | 1500-3500 cycles | 2500-6000 cycles | 3-12× | 5-20× |
| Operation | Sheerpower REAL | Java BigDecimal | Python Decimal | vs Java | vs Python |
|---|---|---|---|---|---|
| Addition | 1-2 cycles | 50-60 cycles | 200-250 cycles | 30-50× | 125-200× |
| Subtraction | 1-2 cycles | 50-60 cycles | 200-250 cycles | 30-50× | 125-200× |
| Multiplication | 6-10 cycles | 80-120 cycles | 400-500 cycles | 10-15× | 50-65× |
| Division (constant) | 25-30 cycles | 200-300 cycles | 1500-2000 cycles | 8-10× | 60-70× |
| Division (cached) | 25-30 cycles | 200-300 cycles | 1500-2000 cycles | 8-10× | 60-70× |
| Division (uncached) | 130-150 cycles | 200-300 cycles | 1500-2000 cycles | 1.5-2× | 12-13× |
/100 for percentage).
| Operation | Sheerpower REAL | Java BigDecimal | Python Decimal | vs Java | vs Python |
|---|---|---|---|---|---|
| Addition | 1 cycle | 50-60 cycles | 200-250 cycles | 50-60× | 200-250× |
| Subtraction | 1 cycle | 50-60 cycles | 200-250 cycles | 50-60× | 200-250× |
| Multiplication | 3 cycles | 60-70 cycles | 350-400 cycles | 20-23× | 115-133× |
| Division (constant) | 5 cycles | 110-130 cycles | 1200-1500 cycles | 22-26× | 240-300× |
| Division (cached) | 5 cycles | 110-130 cycles | 1200-1500 cycles | 22-26× | 240-300× |
| Division (uncached) | 40 cycles | 110-130 cycles | 1200-1500 cycles | 2.75-3.25× | 30-37× |
long.
| Implementation | Cycles per Transaction | Time on a Modern PC | Speedup |
|---|---|---|---|
| Sheerpower REAL | 1+1+10+5+3 = 20 cycles | 10 nanoseconds | Baseline |
| Java BigDecimal | 50+50+100+110+150 = 460 cycles | 230 nanoseconds | 23× slower |
| Python Decimal | 200+200+450+1200+250 = 2,300 cycles | 1,150 nanoseconds | 115× slower |
Real-world impact: Processing a million invoices takes 1 second in Sheerpower vs 23 seconds in Java vs 115 seconds (almost 2 minutes) in Python.
Sheerpower REALs store values using two 64-bit signed integers. This design only became practical, providing high-performance, once 64-bit CPUs became the dominant execution platform.
The 32-bit constraint: In a 32-bit environment, each REAL would require four 32-bit integers to represent the same data. Every arithmetic operation would involve multi-word math, register spills, and helper routines, making exact decimal arithmetic consistently slower than native floating-point hardware.As a result, most mainstream languages committed early to IEEE 754 binary floating-point (standardized in 1985) or to heap-allocated arbitrary-precision libraries such as BigDecimal (introduced in the 1990s). At the time, fast and portable 64-bit integer arithmetic could not be assumed.
What changed: Modern x86-64 CPUs perform 64-bit integer operations at full register speed. Values in the +/-1018 range fit cleanly within signed 64-bit integers (limit +/-9.22 quintillion), and native 64-bit multiplication produces 128-bit results that map naturally onto REAL arithmetic.
Why other languages could not pivot: Billions of lines of existing code depend on floating-point defaults, numeric promotion rules, and historical performance assumptions. Backward compatibility effectively locked those languages into their original numeric models.
Sheerpower REALs were designed specifically for the 64-bit era and the demands of large-scale business applications. In the previous 32-bit landscape, managing two 64-bit integers for every numeric operation was computationally prohibitive. By launching in the 64-bit era, Sheerpower was able to adopt exact decimal arithmetic as its default model—delivering deterministic financial precision at native-integer speeds.
Sheerpower's REAL type utilizes a 128-bit fixed-point decimal representation, internally managed as two 64-bit signed integers. By fixing the decimal scale at 16 digits, the architecture provides computational determinism for base-10 fractions, eliminating the representation drift and epsilon comparison requirements inherent in binary floating-point (IEEE 754) math.
While floating-decimal implementations (like C# decimal or IEEE 754-2008 _Decimal128) offer greater scale flexibility for scientific applications, Sheerpower's split-integer approach is optimized for high-volume transactional logic. It trades dynamic scaling for instruction-level efficiency, mapping decimal arithmetic directly to native 64-bit integer pipelines. This architecture enables near-register speeds for financial calculations.
In this advanced discussion, we delve into Sheerpower's memory management and optimization strategies for handling strings efficiently.
Sheerpower manages strings by reusing memory buffers, which significantly reduces the overhead of memory allocations and deallocations. For example, if a string holds "The rain in Spain" and is later changed to "Enjoy life", Sheerpower repurposes the existing buffer. In most applications, over 99% of string buffers are reused.
This approach avoids the frequent memory operations that cause
performance bottlenecks in other languages.
All strings are over-allocated and virtually mutable, making assignments O(1)
operations with no allocation/deallocation cycles.
In many languages, every string modification requires a new memory allocation, and the old memory must be deallocated. This cycle introduces overhead, especially in loops.
num$. The buffer is reused in each iteration, a stark
contrast to languages that could perform 10,000 allocations and
deallocations, slowing down performance.
Based on research showing 85% of business strings are under 128 bytes, Sheerpower pre-allocates thousands of fixed-size buffers on startup.
Sheerpower assigns every unique string value a 64-bit sequential String ID (SID). When a string variable is first created, the runtime generates a new SID for its content. When another variable is assigned the same content—either by direct assignment or by copying—the SID from the source descriptor is copied into the destination descriptor along with the data. In other words, the SID travels with the data.
The SID is stored directly inside the string's descriptor, alongside the string's length, the pointer to its character buffer, and the buffer's current allocation size. Because the SID lives inside the descriptor rather than in a centralized lookup table, Sheerpower avoids global SID-table lookups and enables several powerful runtime optimizations:
String literal assignments cost almost nothing, as the descriptor simply points to the literal in the compiled code. A copy is only triggered upon modification.
Sheerpower uses an internal hinting mechanism, leveraging SIDs to remember recent operations and cache results. This enhances efficiency by avoiding redundant processing.
Concatenation Hinting: A cache-sized hint array remembers recent concatenation operations by SID combinations. For repetitive tasks like building SQL queries, subsequent operations become simple cache lookups.
Function Parameter Parsing Cache: Functions like
getword$() and geodistance() automatically cache
parsing results by string content.
If you call getword$(bible$, 1000) and then
getword$(bible$, 1001), Sheerpower uses the hint to
quickly find the next word without re-reading from the start.
These transparent optimizations provide the most benefit for typical business application patterns:
Sheerpower's memory management shines in applications where performance is critical, such as real-time data analysis, and large-scale batch processing systems.
By understanding these advanced techniques, you can harness Sheerpower's capabilities to build highly efficient, scalable, and robust applications that handle strings with high performance.
|
Hide Description
|
|
|
Enter or modify the code below, and then click on RUN |
|
Looking for the full power of Sheerpower?
Check out the Sheerpower website. Free to download. Free to use. |