I am submitting a function to the acb library called acb_set_str() since I encountered problems trying to input very high precision complex numbers.
The input can be one flint number in which case the imag value is set to zero. If two flint numbers are input, then a true complex number is obtained. The flint numbers can be bracked with their radius, i.e. [3.14159264 +/- 1e-14] as valid input. To enter a pure imaginary value, simply set the real part to 0. The main test program used quotes to delineate the string for input.
/*
Copyright (C) 2025 Randall L. Rathbun
This file is intended to become part of FLINT.
FLINT is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. See <
https://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
#include "flint/acb.h"
int acb_set_str(acb_t res, const char * inp, slong prec)
{
// test input
// printf("inp = %s\n",inp);
char * buf;
char * split;
const int max_tokens = 6;
char * tokens[max_tokens];
int num_toks = 0;
buf = flint_malloc(strlen(inp) + 1);
strcpy(buf, inp);
// Tokenize input string (by spaces)
split = strtok(buf, " ");
while (split != NULL && num_toks < max_tokens) {
tokens[num_toks++] = split;
split = strtok(NULL, " ");
}
// test tokens
/*
printf("num_toks: %d\n",num_toks);
for ( int ix=0; ix<num_toks; ix++) {
printf("token[%d] = %s\n",ix,tokens[ix]);
}
*/
// Handle different cases based on the number of tokens
int error = 0;
switch (num_toks) {
case 1:
// Single token
error = arb_set_str(acb_realref(res), tokens[0], prec);
if (error) { break; }
arb_zero(acb_imagref(res)); // Set imaginary part to zero
break;
case 2:
// Two tokens
error = arb_set_str(acb_realref(res), tokens[0], prec);
if (error) { break; } else {
error = arb_set_str(acb_imagref(res), tokens[1], prec);
}
break;
case 3:
// Three tokens (one real number with no imaginary part)
if (strcmp(tokens[1], "+/-") == 0) {
// this is strictly a real number +/- variance
char * tmp = flint_malloc(strlen(inp) + 1);
memset(tmp, '\0', sizeof(tmp));
strcat(tmp,tokens[0]); strcat(tmp," "); strcat (tmp,tokens[1]); strcat(tmp," "); strcat(tmp,tokens[2]);
// printf("tmp = %s\n",tmp);
// Set real part
error = arb_set_str(acb_realref(res), tmp, prec);
if (error) { flint_free(tmp); break; }
// set imag to zero
arb_zero(acb_imagref(res)); // Set imaginary part to zero
flint_free(tmp);
}
break;
case 4:
// Four tokens (one real number with variance and pure imaginary number)
if (strcmp(tokens[1], "+/-") == 0) {
// this is strictly a real number +/- variance
char * tmp = flint_malloc(strlen(inp) + 1);
memset(tmp, '\0', sizeof(tmp));
strcat(tmp,tokens[0]); strcat(tmp," "); strcat (tmp,tokens[1]); strcat(tmp," "); strcat(tmp,tokens[2]);
// printf("tmp = %s\n",tmp);
// Set real part
error = arb_set_str(acb_realref(res), tmp, prec);
if (error) { flint_free(tmp); break; }
// set imag to zero
arb_zero(acb_imagref(res)); // Set imaginary part to zero
error = arb_set_str(acb_imagref(res), tokens[3], prec);
if (error) { flint_free(tmp); break; }
flint_free(tmp);
}
break;
case 6:
// six tokens; must have two "+/-"
if (strcmp(tokens[1], "+/-") == 0 && strcmp(tokens[4], "+/-") == 0) {
char * tmp = flint_malloc(strlen(inp) + 1);
memset(tmp, '\0', sizeof(tmp));
strcat(tmp,tokens[0]); strcat(tmp," "); strcat(tmp,tokens[1]); strcat(tmp," "); strcat(tmp,tokens[2]);
// Set real part
error = arb_set_str(acb_realref(res), tmp, prec);
if (error) { flint_free(tmp); break; }
// test real part
/*
printf("real: ");
arb_printd(acb_realref(res), 10); // Print real part
printf("\n");
*/
// Set imaginary part
memset(tmp, '\0', sizeof(tmp));
strcat(tmp,tokens[3]); strcat(tmp," "); strcat(tmp,tokens[4]); strcat(tmp," "); strcat(tmp,tokens[5]);
error = arb_set_str(acb_imagref(res), tmp, prec);
/*
printf("imag: ");
arb_printd(acb_imagref(res), 10); // Print imag part
printf("\n");
*/
if (error) { flint_free(tmp); break; }
flint_free(tmp);
}
break;
default:
// Handle error for unsupported formats
error = 1; // Set appropriate error code
}
flint_free(buf);
return error;
}
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stderr, "Usage: %s <input_string>\n", argv[0]);
return 1;
}
arb_t real;
arb_init(real);
acb_t result;
acb_init(result);
slong precision = 50; // Example precision
int error = acb_set_str(result, argv[1], precision);
if (error) {
fprintf(stderr, "Error setting complex number from string.\n");
} else {
printf("Complex number: [");
arb_printd(acb_realref(result), 10); // Print real part
printf("] + [");
arb_printd(acb_imagref(result), 10); // Print imaginary part
printf("]*i\n");
}
arb_clear(real);
acb_clear(result);
return 0;
}