Submitted:
31 March 2026
Posted:
01 April 2026
You are already at the latest version
Abstract
Keywords:
1. Introduction
1.1. Background and Motivation
- Information preservation: The printed result must be parseable back to the original floating-point number without loss of precision.
- Minimum length: The output string should be as short as possible while maintaining information preservation.
- Correct rounding: When multiple representations satisfy the first two criteria, the algorithm must correctly round to the nearest value, with ties broken by selecting the even value.
- Left-to-right generation: The output digits should be generated sequentially from the most significant to the least significant digit.
- dtoa.c [3] is an improved version of Dragon4, written by Robert G. Burger and R. Kent Dybvig in 1996. The source code link is https://www.netlib.org/fp/dtoa.c.
- Grisu3 [4] pioneered the use of precomputed powers of ten to avoid expensive arbitrary-precision operations, though it occasionally falls back to slower methods for certain inputs.
- Errol [5] improved upon Grisu3 by reducing the fallback rate through more precise error analysis.
- Schubfach [8] introduced a novel approach based on the concept of "Schubfach" (pigeonhole principle), providing a compact and elegant solution with competitive performance.
- Grisu-Exact [9] eliminated the need for fallbacks entirely while maintaining high performance.
- Dragonbox [10] reduces the number of multiplications by sacrificing more branches.
- yy_double [11] explored alternative computational strategies to minimize the multiplication cost, but there were still a few branches.
- zmij [15] is based on yy_double and has undergone extensive code optimization.
- 1.
- Branch prediction penalties: Many algorithms rely heavily on conditional branches to handle different cases, leading to frequent branch mispredictions on modern pipelined processors.
- 2.
- High-precision multiplication overhead: The conversion process requires high-precision arithmetic operations, particularly multiplications involving large precomputed constants, which can be expensive on standard hardware.
- 3.
- Instruction dependency chains: Sequential dependencies between operations limit instruction-level parallelism and prevent efficient utilization of modern superscalar processors.
- 4.
- Limited SIMD utilization: Most existing algorithms do not exploit vector instruction sets (SIMD) that are now ubiquitous in contemporary processors.
1.2. Contributions
- 1.
- Reduced instruction dependencies: By carefully restructuring the computation, xjb minimizes data dependencies between operations, enabling better instruction-level parallelism and improved pipeline utilization.
- 2.
- Minimized multiplication operations: The algorithm reduces the number of expensive high-precision multiplications required during conversion, significantly decreasing computational overhead.
- 3.
- Mitigated branch prediction penalties: Through branchless programming techniques and careful case analysis, xjb minimizes conditional branches that could lead to prediction failures.
- 4.
- SIMD instruction utilization: The algorithm is designed to leverage SIMD instructions where applicable.
- 5.
- Concise core implementation: Despite its sophisticated optimizations, xjb maintains a compact and readable core implementation, facilitating adoption and maintenance.
1.3. Evaluation Overview
1.4. Explanation of Special Symbols in This Article
| symbol | brief explanation | example |
|---|---|---|
| % | Integer modulus operation | 2 = 8%3 |
| // | Integer division operation | 1 = 5//3 |
| or | Left or right shift of binary values | 8 = 13 |
| ? : | Similar to the ternary operator in C syntax | a = 1?a:b |
2. IEEE754 Floating-Point Number Representation
2.1. Scope and Assumptions
- We consider only positive floating-point numbers, as negative numbers differ only by a leading minus sign.
- We exclude special values (zero, NaN, and infinity) from our analysis, as these are handled separately in practice.
2.2. Binary Representation
- 1 sign bit (s): indicates positive () or negative ().
- 11 exponent bits (e): biased exponent in the range .
- 52 fraction bits (f): significand fraction in the range .
- 1 sign bit (s): indicates positive () or negative ().
- 8 exponent bits (e): biased exponent in the range .
- 23 fraction bits (f): significand fraction in the range .
2.3. Classification of Floating-Point Numbers
- 1.
- Subnormal numbers ( and ): These represent very small values close to zero, where the implicit leading bit of the significand is 0 instead of 1.
- 2.
- Normal numbers ( and ): The standard case where the implicit leading bit of the significand is 1.
- 3.
- Irregular numbers ( and ): Numbers with zero fraction field, representing powers of two.
2.4. Value Representation
2.5. Rounding Intervals
3. Principle of Algorithm
3.1. Design Overview
- 1.
- Float-to-Decimal Conversion: Converting binary floating-point values to decimal significand-exponent pairs .
- 2.
- Decimal-to-String Conversion: Formatting into human-readable strings.
- Minimize branch mispredictions through unlikely branches and branchless techniques
- Reduce expensive high-precision multiplication operations
- Optimize instruction dependencies to enable better parallelism
- Maintain core implementation simplicity and readability
3.2. Mathematical Foundation
3.3. Review of the Schubfach Algorithm and Our Derivation
3.3.1. Candidate Values for the Significand d
3.3.2. Decomposition into Integer and Fractional Parts
3.3.3. Selection Criteria for
-
Case (i.e., ): This case applies when is the closest representable decimal to v within the rounding interval. The condition is derived as follows:The lower bound of the rounding interval must be less than :When equality holds (), we apply the round-to-even rule, requiring c to be even:
-
Case (i.e., ): This case applies when is the closest representable decimal to v. The condition is derived similarly:The upper bound of the rounding interval must be greater than :When equality holds (), we again apply round-to-even:
-
Case : When neither boundary condition applies, the optimal value lies between and . We determine by rounding to the nearest integer:
- –
- If the fractional part :
- –
- If the fractional part :
- –
- If the fractional part : apply round-to-even
For irregular floating-point numbers (powers of two), additional verification is required to ensure the selected value lies within the rounding interval , as the interval boundaries differ for these special cases.
3.3.4. Algorithm Overview
- 1.
- Lookup table precomputation
- 2.
- Efficient computation of m
- 3.
- Fast boundary condition testing for
- 4.
- Efficient computation of and rounding
- 5.
- Handling of irregular floating-point numbers
- 6.
- implementation of pseudocode
| Algorithm 1:The xjb Algorithm for Float-to-Decimal Conversion |
|
3.4. Lookup Table Precomputation
3.4.1. Fundamental Calculation
3.4.2. Detailed Calculation Process
-
FloatThe range of is calculated to be [-32, 44] through the q value range in Equation (6), so the lookup table contains representation values from 10 to the power of -32 to 10 to the power of 44. The calculation process is as follows:When , the lookup table variable indicates that the values and are equal. In other cases, the relative error is less than . Expressed as:
-
DoubleThe range of is calculated to be [-293, 323] through the q value range in Equation (6), so the lookup table contains representation values from 10 to the power of -293 to 10 to the power of 323. The calculation process is as follows:When , the lookup table variable indicates that the values and are equal. In other cases, the relative error is less than . Expressed as:
3.4.3. Storage Requirements
3.4.4. Implementation Notes
3.5. Efficient Computation of m
3.5.1. Relevant Theorems
3.5.2. Best Rational Approximation Function
3.5.3. Key Proof
3.5.4. Bit Width Calculation
3.5.5. Results
3.6. Fast Boundary Condition Testing for and
3.6.1. Equivalent Conditions for Boundary Testing
Case 1: Testing
Case 2: Testing
3.6.2. Integer Testing Analysis
Analysis for
Analysis for
3.6.3. Key Insight: Integer Divisibility Test
-
Case : From , we get . The expression simplifies to checking if is divisible by . Since 2 and 5 are coprime, this reduces to checking if is divisible by :Let t be a positive integer such that . Since is odd, t must also be odd. Considering the ranges of c for float and double:This gives us the range for t:The maximum values of k where t can be at least one odd integer are:
- Case : The denominator is even, while the numerator is odd, so no solution exists.
- Case : The denominator is even, while the numerator is odd, so no solution exists.
3.6.4. Summary of Boundary Conditions
3.6.5. Efficient Implementation
-
When , is the expression (79), the following holds true:Therefore, when , Equation (76) does not hold true.
-
Call function (35) to calculate the approximation results and of all possible upper and lower limit rational numbers:Therefore, for , the following conclusion can be drawn from formula (34).Therefore, when , Equation (76) does not hold true.
-
When , is the expression (92), the following holds true:Therefore, when , Equation (89) does not hold true.
-
Call function (35) to calculate the approximation results and of all possible upper and lower limit rational numbers:Therefore, for , the following conclusion can be drawn from formula (34).Therefore, when , Equation (89) does not hold true.
3.7. Efficient Computation of and Rounding
3.7.1.
-
When , it can be concluded that , the numerator is even and the denominator is odd, which does not meet the condition.
-
When , it can be concluded that is even, which does not meet the condition.
-
is an odd number. c is an odd multiple of . So:Therefore, when q meets the above conditions, c must be an odd multiple of to meet the condition. Therefore, when the following conditions are met, expression (141) is an odd number:The following equation holds:Since , is multiple of 5 and is an odd number. Since and are both odd numbers, is an even number, is multiple of 5 and is an odd number. Therefore, there is:The result of is an even number between and . Therefore:
3.7.2.
3.7.3. Efficient Implementation of for Double
3.7.4. Efficient Calculation of for Double
3.8. Irregular Number
3.9. Implementation of Pseudocode
3.9.1. Single-Precision Floating-Point Numbers
3.9.2. Double-Precision Floating-Point Numbers
3.10. Decimal to String Conversion
Scalar Implementation
| Algorithm 2:Convert an 8-digit decimal number to ASCII: dec_to_ascii8(x) |
|
| Algorithm 3:Convert a 16-digit decimal number to ASCII: dec_to_ascii16(x) |
|
Handling Undefined Behavior
SIMD Implementation
| Algorithm 4:Floating-point number printing algorithm |
|
3.11. Summary
- Section 3.5 introduces the method for quickly calculating m.
- Section 3.6 and Section 3.7 introduce the methods for quickly calculating .
- Section 3.9 provides a detailed description of the pseudo-code implementation.
- Section 3.10 discusses print optimization.
| algorithm | float | double | description |
|---|---|---|---|
| Schubfach | Schubfach32 | Schubfach64 | author:Raffaello Giulietti,https://github.com/c4f7fcce9cb06515/Schubfach. |
| Schubfach_xjb | Schubfach32_xjb | Schubfach64_xjb | It is improved by Schubfach and has the same output result. |
| Ryu | Ryu32 | Ryu64 | author:Ulf Adams,https://github.com/ulfjack/ryu. |
| Dragonbox | Dragonbox32 | Dragonbox64 | author:Junekey Jeon,https://github.com/jk-jeon/Dragonbox. |
| fmt [22] | fmt32 | fmt64 | author:Victor Zverovich,https://github.com/fmtlib/fmt version:12.1.0 |
| yy_double | - | yy_double | author:GuoYaoYuan,link:yy_double. |
| yy_json [23] | yy_json32 | yy_json64 | author:Guo YaoYuan,https://github.com/ibireme/yyjson version:0.12.0 |
| teju_jagua [24] | teju32 | teju64 | author:Cassio Neri,https://github.com/cassioneri/teju_jagua. |
| xjb | xjb32 | xjb64 | this paper,https://github.com/xjb714/xjb. |
| zmij | zmij32 | zmij64 | author:Victor Zverovich,https://github.com/vitaut/zmij. |
| jnum [25] | jnum32 | jnum64 | author:Jing Leng,https://github.com/lengjingzju/json/jnum.c. |
| uscalec | - | uscalec | author:Russ Cox,src:https://github.com/rsc/fpfmt commit 6255750 (19 Jan 2026). |
4. Experimental Evaluation
4.1. Correctness Verification
- Single-precision (float): We tested all possible input values ( values) and verified that the output matches the Schubfach algorithm, ensuring complete correctness for the binary32 format.
- Double-precision (double): Due to the impracticality of exhaustively testing all possible values, we conducted comprehensive random testing with a large sample size to verify correctness for the binary64 format.
4.2. Experimental Setup
4.2.1. Hardware Platforms
- AMD Ryzen 7 7840H: A modern x86-64 processor with support for AVX2 and AVX-512 instruction sets, running Ubuntu 26.04.
- Apple M1: A representative ARM-based processor with NEON SIMD support, running macOS 26.4.
4.2.2. Compilers and Compilation Flags
- AMD R7-7840H: Intel C++ Compiler (icpx) version 2025.0.4
- Apple M1: Apple Clang version 21.0.0
4.2.3. Benchmark Methodology
- 1.
- Generate random floating-point numbers, excluding special values (0, NaN, and Inf).
- 2.
- Measure the total time required to convert all numbers to decimal representation.
- 3.
- Calculate the average conversion time per floating-point number.
4.3. Algorithms Compared
- Schubfach: The baseline algorithm from which xjb is derived.
- Schubfach_xjb: A variant of Schubfach with xjb optimizations.
- Ryu: A widely-used high-performance algorithm.
- Dragonbox: Another state-of-the-art algorithm with competitive performance.
- fmt: A modern formatting library.
- yy_json / yy_double: Fast algorithms optimized for JSON serialization.
- teju_jagua: A recent algorithm (note: only supports float/double to decimal conversion).
- zmij: A modern algorithm with competitive performance.
- uscalec: An algorithm supporting double-precision only.
4.4. Performance Results
4.5. Analysis and Discussion
4.5.1. Performance Comparison
- For float-to-decimal conversion, xjb achieves 2.24 ns, which is 1.98× faster than the second-fastest algorithm (Schubfach_xjb at 4.44 ns) and 5.44× faster than the baseline Schubfach (12.2 ns).
- For double-to-decimal conversion, xjb achieves 3.76 ns, which is 1.27× faster than the second-fastest algorithm (yy_double at 5.24 ns) and 3.06× faster than the baseline Schubfach (11.51 ns).
- For float-to-string conversion, xjb is about 60% faster than zmij.
- For double-to-string conversion, xjb is about 8% faster than zmij.
- For float-to-decimal conversion, xjb achieves 2.15 ns, which is 1.84× faster than the second-fastest algorithm (zmij at 4.11 ns) and 5.41× faster than the baseline Schubfach (11.64 ns).
- For double-to-decimal conversion, xjb achieves 2.58 ns, which is 1.49× faster than the second-fastest algorithm (yy_double at 4.08 ns) and 5.08× faster than the baseline Schubfach (13.12 ns).
- For float-to-string conversion, xjb is about 96% faster than zmij.
- For double-to-string conversion, xjb is about 20% faster than zmij.
4.5.2. Performance Consistency
4.5.3. Cross-Platform Performance
- On x86-64 (AMD R7-7840H), xjb benefits from the compiler’s ability to generate efficient code for the algorithm’s arithmetic operations.
- On ARM64 (Apple M1), xjb maintains its performance advantage, demonstrating the algorithm’s portability and effectiveness across different instruction set architectures.
4.5.4. Comparison with Related Algorithms
- vs. Schubfach: xjb achieves 3–5× speedup over the baseline Schubfach algorithm, validating the effectiveness of our optimizations in reducing multiplication operations and minimizing branch prediction penalties.
- vs. yy_json/yy_double: While these algorithms are highly optimized for JSON serialization workloads, xjb outperforms them by 1.3–1.8×, demonstrating broader applicability beyond specific use cases.
- vs. zmij: xjb achieves 1.5–1.9× speedup over zmij, another recent high-performance algorithm, showing the benefits of our approach to instruction dependency reduction.
- vs. Ryu and Dragonbox: xjb significantly outperforms these widely-used algorithms (2.5–6× faster), demonstrating that the optimizations in xjb provide substantial benefits over established approaches.
4.6. Summary
- 1.
- Consistently superior performance across both x86-64 and ARM64 architectures.
- 2.
- Significant speedups over the baseline Schubfach algorithm (3–5×).
- 3.
- Competitive or superior performance compared to all other state-of-the-art algorithms.
- 4.
- Stable performance regardless of input distribution due to effective branch prediction optimization.
5. Conclusions
5.1. Summary of Contributions
- 1.
- Reduced computational complexity: By restructuring the calculation process and minimizing the number of high-precision multiplication operations, xjb achieves substantial performance improvements over the baseline Schubfach algorithm.
- 2.
- Optimized branch structure: The algorithm employs unlikely branch patterns that enable efficient branch prediction on modern processors, resulting in consistent performance across diverse input distributions.
- 3.
- Cross-platform portability: xjb demonstrates excellent performance across both x86-64 and ARM64 architectures, making it suitable for deployment in heterogeneous computing environments.
- 4.
- Comprehensive validation: The algorithm has been thoroughly tested and verified to produce correct output for all IEEE 754 binary32 and binary64 floating-point values.
5.2. Experimental Findings
- 3–5× speedup over the baseline Schubfach algorithm
- Faster than other high-performance algorithms such as yy_json, yy_double, and zmij
- Consistent performance across different input patterns and hardware platforms
5.3. Practical Implications
- Data serialization: JSON and other text-based data formats require efficient floating-point to string conversion for serialization operations.
- Scientific computing: Applications that output numerical results in human-readable format benefit from faster conversion without sacrificing accuracy.
- Database systems: Export operations and query result formatting can leverage xjb for improved throughput.
- Web services: RESTful APIs and web applications that return numerical data can achieve lower latency with efficient conversion.
5.4. Limitations and Future Work
- 1.
- Extended precision support: Future work could extend xjb to support extended precision formats (e.g., 80-bit and 128-bit floating-point numbers) for applications requiring higher precision.
- 2.
- SIMD vectorization: Although xjb is designed to be SIMD-friendly, explicit vectorization using AVX-512 or NEON could yield additional performance gains for batch conversion workloads.
- 3.
- Compiler compatibility: Further optimization for different compilers (particularly MSVC) would improve portability across development environments.
- 4.
- Memory-constrained environments: Investigating memory-efficient variants of xjb could benefit embedded systems and other resource-constrained platforms.
5.5. Availability
References
- Steel, G. L., Jr.; White, J. L. How to Print Floating-Point Numbers Accurately. In Proceedings of the ACM SIGPLAN 1990 Conference on Programming Language Design and Implementation, PLDI, New York, NY, USA; ACM, 1990; pp. 112–126. [Google Scholar] [CrossRef]
- Steel, G. L., Jr.; White, J. L. How to Print Floating-Point Numbers Accurately (Retrospective). ACM SIGPLAN Notices;Best of PLDI 2004, 39(4), 1979–1999. Available online: https://dl.acm.org/doi/10.1145/989393.989431.
- Burger, Robert G.; Dybvig, R. Kent. Printing Floating-point Numbers Quickly and Accurately. In Proceedings of the ACM SIGPLAN1996 Conference on Programming Language Design and Implementation (PLDI ’96), New York, NY, USA, 1996; ACM; p. 108ś116. [Google Scholar] [CrossRef]
- Loitsch, F. Printing Floating-Point Numbers Quickly and Accurately with Integers. In Proceedings of the ACM SIGPLAN 2010 Conference on Programming Language Design and Implementation, PLDI 2010. ACM, New York, NY, USA; pp. 233–243. [CrossRef]
- Andrysco, M.; Jhala, R.; Lerner, S. Printing Floating-Point Numbers: a Faster, Always Correct Method. In Proceedings of the 43rd Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, POPL 2016. ACM, New York, NY, USA; pp. 555–567. [CrossRef]
- Adams, Ulf. Ryu¯: Fast Float-to-String Conversion. Proceed- ings of 39th ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI’18), New York, NY, USA, 2018; ACM; p. 13 pages. [Google Scholar] [CrossRef]
- Adams, Ulf. Ryu¯ Revisited: Printf Floating Point Conversion. Proc. ACM Program. Lang. 3, OOPSLA, October 2019; 2019; Article 169, p. 23 pages. [Google Scholar] [CrossRef]
- Giulietti, R. The Schubfach Way to Render Doubles. 2020. Available online: https://drive.google.com/file/d/1KLtG_LaIbK9ETXI290zqCxvBW94dj058/view.
- Jeon, J. Grisu-Exact: A Fast and Exact Floating-Point Printing Algorithm. 2020. Available online: https://github.com/jk-jeon/Grisu-Exact/blob/master/other_files/Grisu-Exact.pdf.
- Jeon, Junekey. Dragonbox: A New Floating-Point Binary-to-Decimal Conversion Algorithm. 2024. Available online: https://github.com/jk-jeon/Dragonbox.
- YaoYuan, Guo. Nov 2024. Available online: https://github.com/ibireme/c_numconv_benchmark/blob/master/vendor/yy_double/yy_double.c.
- Cox, Russ. Jan 2026. Available online: https://github.com/rsc/fpfmt.
- Cox, Russ. Floating-Point Printing and Parsing Can Be Simple And Fast. Jan 2026. Available online: https://research.swtch.com/fp.
- Cox, Russ. Fast Unrounded Scaling: Proof by Ivy. Jan 2026. Available online: https://research.swtch.com/fp-proof.
- Zverovich, Victor. Mar 2026. Available online: https://github.com/vitaut/zmij.
- IEEE Standard for Binary Floating-Point Arithmetic. ANSI/IEEE Std 754-1985 1985, vol., no., 1–20. [CrossRef]
- IEEE Standard for Floating-Point Arithmetic. IEEE Std 754-2019 (Revision of IEEE 754-2008) 2019, vol., no., 1–84. [CrossRef]
- Khuong, Paul. How to print integers really fast (with Open Source AppNexus code!). Dec 2017. Available online: https://pvk.ca/Blog/2017/12/22/appnexus-common-framework-its-out-also-how-to-print-integers-faster/.
- Johnson, Dougall. Converting integers to fixed-width strings faster with Neon SIMD on the Apple M1. Apr 2022. Available online: https://dougallj.wordpress.com/2022/04/01/converting-integers-to-fixed-width-strings-faster-with-neon-simd-on-the-apple-m1/.
- Muła, Wojciech. SSE: conversion integers to decimal representation. Oct 2011. Available online: http://0x80.pl/notesen/2011-10-21-sse-itoa.html.
- Lemire, Daniel. Converting integers to decimal strings faster with AVX-512. Mar 2022. Available online: https://lemire.me/blog/2022/03/28/converting-integers-to-decimal-strings-faster-with-avx-512/.
- Zverovich, Victor. Oct 2025. Available online: https://github.com/fmtlib/fmt.
- YaoYuan, Guo. Aug 2025. Available online: https://github.com/ibireme/yyjson.
- Neri, Cassio. Nov 2025. Available online: https://github.com/cassioneri/teju_jagua.
- Leng, Jing. Nov 2025. Available online: https://github.com/lengjingzju/json/jnum.c.

| Category | Float (binary32) | Double (binary64) |
|---|---|---|
| Subnormal | , | , |
| Normal | ||
| Irregular | , | , |
| float number | fixed-point | scientific |
|---|---|---|
| 2.34 | “2.34” | “2.34e+00" |
| 12 | “12.0" | “1.2e+01" |
| 120 | “120.0" | “1.2e+02" |
| 0.012 | “0.012" | “1.2e-02" |
| SIMD implementation | Description |
|---|---|
| NEON [19] | Original author: Dougall Johnson. Runs on ARM processors with NEON instruction set. |
| SSE2 [20] | Based on scalar version; requires only SSE2 instruction set. |
| SSE4.1 | Nearly identical to SSE2 implementation; requires SSE4.1 instruction set. |
| AVX512 [21] | Original author: Daniel Lemire. Requires AVX512IFMA and AVX512VBMI instruction sets. |
| Type | Fixed-point | Scientific |
|---|---|---|
| float | other ranges | |
| double | other ranges |
| algorithm | float | double | |
|---|---|---|---|
| icpx 2025.0.4 | icpx 2025.0.4 | ||
| Schubfach | 12.2 | 11.51 | |
| Schubfach_xjb | 4.44 | 6.33 | |
| Ryu | 14.02 | 13.08 | |
| Dragonbox | 10.19 | 10.05 | |
| yy_json | 4.67 | 5.72 | |
| yy_double | - | 5.24 | |
| teju_jagua | 14.99 | 14.37 | |
| zmij | 4.76 | 4.78 | |
| uscalec | - | 11.27 | |
| xjb | 2.24 | 3.76 | |
| algorithm | float | double | |
|---|---|---|---|
| apple clang 21.0.0 | apple clang 21.0.0 | ||
| Schubfach | 11.64 | 13.12 | |
| Schubfach_xjb | 5.16 | 6.58 | |
| Ryu | 15.75 | 14.16 | |
| Dragonbox | 11.78 | 12.03 | |
| yy_json | 3.97 | 4.46 | |
| yy_double | - | 4.08 | |
| teju_jagua | 20.25 | 18.66 | |
| zmij | 4.11 | 3.83 | |
| uscalec | - | 15.26 | |
| xjb | 2.15 | 2.58 | |
Disclaimer/Publisher’s Note: The statements, opinions and data contained in all publications are solely those of the individual author(s) and contributor(s) and not of MDPI and/or the editor(s). MDPI and/or the editor(s) disclaim responsibility for any injury to people or property resulting from any ideas, methods, instructions or products referred to in the content. |
© 2026 by the authors. Licensee MDPI, Basel, Switzerland. This article is an open access article distributed under the terms and conditions of the Creative Commons Attribution (CC BY) license (http://creativecommons.org/licenses/by/4.0/).