X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fanalog.c;h=634e9a674ba8ada7817bd489d68bedbe7853ed59;hb=962172e4950f3fbc42d5a79cdf63dc179d7513be;hp=7343b481e610d409d51bb45dd5f2be1a31138c77;hpb=17d5a11c69ebd7dd0a62a6e2466d3d8ce05b9d03;p=libsigrok.git diff --git a/src/analog.c b/src/analog.c index 7343b481..634e9a67 100644 --- a/src/analog.c +++ b/src/analog.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "libsigrok-internal.h" @@ -292,6 +293,37 @@ SR_API int sr_analog_to_float(const struct sr_datafeed_analog *analog, return SR_OK; } +/** + * Scale a float value to the appropriate SI prefix. + * + * @param[in,out] value The float value to convert to appropriate SI prefix. + * @param[in,out] digits The number of significant decimal digits in value. + * + * @return The SI prefix to which value was scaled, as a printable string. + * + * @since 0.5.0 + */ +SR_API const char *sr_analog_si_prefix(float *value, int *digits) +{ +#define NEG_PREFIX_COUNT 5 /* number of prefixes below unity */ +#define POS_PREFIX_COUNT (int)(ARRAY_SIZE(prefixes) - NEG_PREFIX_COUNT - 1) + static const char *prefixes[] = { "f","p","n","µ","m","","k","M","G","T" }; + + if (value == NULL || digits == NULL || isnan(*value)) + return prefixes[NEG_PREFIX_COUNT]; + + float logval = log10f(fabsf(*value)); + int prefix = (logval / 3) - (logval < 1); + + if (prefix < -NEG_PREFIX_COUNT) prefix = -NEG_PREFIX_COUNT; + if (3 * prefix < -*digits) prefix = (-*digits + 2 * (*digits < 0)) / 3; + if (prefix > POS_PREFIX_COUNT) prefix = POS_PREFIX_COUNT; + + *value *= powf(10, -3 * prefix); + *digits += 3 * prefix; + return prefixes[prefix + NEG_PREFIX_COUNT]; +} + /** * Convert the unit/MQ/MQ flags in the analog struct to a string. *