pastebin - collaborative debugging tool
rovema.kpaste.net RSS


rov_int_mandelbrot_test1.c - math test module for |template <typename T> class rov_int_template|
Posted by Anonymous on Fri 27th Mar 2026 13:22
raw | new post
modification of post by Anonymous (view diff)

  1. /*
  2.  * MIT License
  3.  *
  4.  * Copyright (c) 2026 Roland Mainz <roland.mainz@nrubsig.org>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  7.  * of this software and associated documentation files (the "Software"), to deal
  8.  * in the Software without restriction, including without limitation the rights
  9.  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10.  * copies of the Software, and to permit persons to whom the Software is
  11.  * furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included in all
  14.  * copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19.  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22.  * SOFTWARE.
  23.  */
  24.  
  25. /*
  26.  * rov_int_mandelbrot_test1.c - math test module for |template <typename T> class rov_int_template|
  27.  *
  28.  * WARNING: This module must be compileable with ISO C and ISO C++ compilers
  29.  * for benchmarking and testing purposes!
  30.  */
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <stdint.h>
  35.  
  36. #include <iostream>
  37.  
  38. #define USE_ROV_INT_TEMPLATE002_TYPES 1
  39.  
  40. #ifdef USE_ROV_INT_TEMPLATE002_TYPES
  41. /*
  42.  * Compile with ISO C++ integer wrapper class
  43.  */
  44. #include "rov_int_template002.h"
  45.  
  46. typedef rov_int_template<int32_t> test_int32_t;
  47. typedef rov_int_template<int64_t> test_int64_t;
  48. #else
  49. /*
  50.  * Compile with ISO C99/C11 compiler
  51.  */
  52. #error XXX
  53. typedef int32_t test_int32_t;
  54. typedef int64_t test_int64_t;
  55. #endif /* USE_ROV_INT_TEMPLATE002_TYPES */
  56.  
  57. /* Mandelbrot parameters */
  58. #define MANDELBROT_VIEW_WIDTH           (132LL) /*72*/
  59. #define MANDELBROT_VIEW_HEIGHT          (3*25LL)
  60. #define MANDELBROT_VIEW_MAX_ITER        (75)
  61.  
  62. /* Fixed-point math (fpx) scale */
  63. #define FPX_SCALE       (1000LL)  /* fpx scale: 1000 <--> 1.0 */
  64.  
  65. /*
  66.  * |fpx_mul()| - fpx multiply: (a*b)/FPX_SCALE using 64-bit
  67.  */
  68. static inline
  69. test_int32_t fpx_mul(test_int32_t a, test_int32_t b)
  70. {
  71.     return (test_int32_t)(((test_int64_t)a * (test_int64_t)b) / FPX_SCALE);
  72. }
  73.  
  74. /*
  75.  * Iterations && ASCII "palette"
  76.  * - FIXME: Make this a cmdline argument
  77.  */
  78. static const char mandelbrot_palette[] =
  79.     " .':;-~=+*0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%&$#";
  80. const size_t mandelbrot_palette_len = sizeof(mandelbrot_palette) - 1;
  81.  
  82. static
  83. void do_fxmath_mandelbrot(void)
  84. {
  85.     /*
  86.      * Mandelbrot view window:
  87.      * fpx: x in [-2, 1], y range adjusted for aspect
  88.      */
  89.     const test_int32_t x_min   = -2000;  /* was: -2.000 * FPX_SCALE */
  90.     const test_int32_t x_max   =  1000;  /* was: 1.000 * FPX_SCALE */
  91.     const test_int32_t x_range = x_max - x_min;
  92.  
  93.     /* y_range = x_range * MANDELBROT_VIEW_HEIGHT / MANDELBROT_VIEW_WIDTH, centered around 0 */
  94.     const test_int32_t y_range =
  95.         (test_int32_t)(((test_int64_t)x_range * MANDELBROT_VIEW_HEIGHT) / MANDELBROT_VIEW_WIDTH);
  96.     const test_int32_t y_min   = -(y_range / 2);
  97.     const test_int32_t y_max   =  (y_range - y_range / 2);
  98.  
  99.     /* Precompute escape radius squared, scaled: (2*FPX_SCALE)^2 */
  100.     const test_int64_t esc2 = (test_int64_t)((2LL * FPX_SCALE) * (2LL * FPX_SCALE));
  101.  
  102.     for (int j = 0; j < MANDELBROT_VIEW_HEIGHT; j++) {
  103.         /* cy = y_min + j * (y_max - y_min) / (MANDELBROT_VIEW_HEIGHT-1) */
  104.         test_int32_t cy = y_min;
  105.  
  106.         test_int64_t t = (test_int64_t)(y_max - y_min);
  107.         t = (t * (test_int64_t)j) / (test_int64_t)(MANDELBROT_VIEW_HEIGHT - 1);
  108.         cy = (test_int32_t)((test_int64_t)y_min + t);
  109.  
  110.         for (int i = 0; i < MANDELBROT_VIEW_WIDTH; i++) {
  111.             /* cx = x_min + i * x_range / (MANDELBROT_VIEW_WIDTH-1) */
  112.             test_int32_t cx = x_min;
  113.  
  114.             test_int64_t t = (test_int64_t)x_range;
  115.             t = (t * (test_int64_t)i) / (test_int64_t)(MANDELBROT_VIEW_WIDTH - 1);
  116.             cx = (test_int32_t)((test_int64_t)x_min + t);
  117.  
  118.             test_int32_t zx = 0, zy = 0;
  119.             int iter = 0;
  120.  
  121.             /* Loop in fpx: z_{n+1} = z_n^2 + c */
  122.             for (;;) {
  123.                 test_int64_t sumsq = (test_int64_t)zx * (test_int64_t)zx + (test_int64_t)zy * (test_int64_t)zy;
  124.                 if (sumsq > esc2)
  125.                         break;
  126.                 if (iter >= MANDELBROT_VIEW_MAX_ITER)
  127.                         break;
  128.  
  129.                 test_int32_t zx2 = fpx_mul(zx, zx);
  130.                 test_int32_t zy2 = fpx_mul(zy, zy);
  131.                 test_int32_t xy  = fpx_mul(zx, zy);
  132.  
  133.                 test_int32_t nx = (zx2 - zy2) + cx;
  134.                 test_int32_t ny = (test_int32_t)((test_int64_t)xy * 2) + cy;
  135.  
  136.                 zx = nx;
  137.                 zy = ny;
  138.                 iter++;
  139.             }
  140.  
  141.             /* Map mandelbrot iterations to palette index */
  142.             size_t idx = (iter >= MANDELBROT_VIEW_MAX_ITER)
  143.                 ? (mandelbrot_palette_len - 1)
  144.                 : (int)(((test_int64_t)iter * (mandelbrot_palette_len - 1)) / MANDELBROT_VIEW_MAX_ITER);
  145.             (void)putchar(mandelbrot_palette[idx]);
  146.         }
  147.  
  148.         (void)putchar('\n');
  149.     }
  150. }
  151.  
  152. static
  153. void do_unit_tests1(void)
  154. {
  155.         /*
  156.          * FIXME: clang++ throws SIGFPE on Debian Bulleye, we need to add code to catch this
  157.          */
  158.         {
  159.                 rov_int_template<int32_t> x = 0;
  160.                 rov_int_template<int32_t> y = 0;
  161.                 try {
  162.                         (void)printf("res (x/y)=%d\n", (int)(x/y));
  163.                         std::cerr << "Test FAILED for " << "(x/y)\n";
  164.                 }
  165.                 catch (const std::exception& e) {
  166.                         std::cerr << "Caught exception: " << e.what() << " (expected - test OK)\n";
  167.                 }
  168.         }
  169.         {
  170.                 rov_int_template<int32_t> x = 0;
  171.                 try {
  172.                         (void)printf("res (x/0)=%d\n", (int)(x/0));
  173.                         std::cerr << "Test FAILED for " << "(x/0)\n";
  174.                 }
  175.                 catch (const std::exception& e) {
  176.                         std::cerr << "Caught exception: " << e.what() << " (expected - test OK)\n";
  177.                 }
  178.         }
  179.         {
  180.                 rov_int_template<int32_t> x = 0;
  181.                 rov_int_template<int32_t> y = 0;
  182.                 try {
  183.                         (void)printf("res (x/=y)=%d\n", (int)(x/=y));
  184.                         std::cerr << "Test FAILED for " << "(x/=y)\n";
  185.                 }
  186.                 catch (const std::exception& e) {
  187.                         std::cerr << "Caught exception: " << e.what() << " (expected - test OK)\n";
  188.                 }
  189.         }
  190. }
  191.  
  192. static
  193. void do_unit_tests2_template_nesting(void)
  194. {
  195. #ifdef DISABLED_FOR_NOW
  196.         {
  197.                 /*
  198.                  * Nested template testcase
  199.                  * We use this for:
  200.                  * 1. compiler testing (some compilers like g++ and clang++ have
  201.                  * issues with this
  202.                  * 2. benchmarking, because we can get extra levels of
  203.                  * indirection easily over all affected components, except if we hit [1]
  204.                  */
  205.                 rov_int_template<rov_int_template<rov_int_template<rov_int_template<int32_t>>>> x = 1;
  206.                 rov_int_template<rov_int_template<rov_int_template<rov_int_template<int32_t>>>> y = 2;
  207.                 (void)printf("res (x+y)=%d\n", int((x+y).get().get().get()));
  208.         }
  209. #endif /* DISABLED_FOR_NOW */
  210. }
  211.  
  212. int main(int ac, char *av[])
  213. {
  214. #if 1
  215.         do_unit_tests1();
  216.         do_unit_tests2_template_nesting();
  217. #endif
  218.  
  219. #if 1
  220.         do_fxmath_mandelbrot();
  221. #endif
  222.         return EXIT_SUCCESS;
  223. }

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at