@@ -674,14 +674,28 @@ static ssize_t __iio_format_value(char *buf, size_t offset, unsigned int type,
else
return sysfs_emit_at(buf, offset, "%d.%09u", tmp0,
abs(tmp1));
- case IIO_VAL_FRACTIONAL_LOG2:
- tmp2 = shift_right((s64)vals[0] * 1000000000LL, vals[1]);
- tmp0 = (int)div_s64_rem(tmp2, 1000000000LL, &tmp1);
- if (tmp0 == 0 && tmp2 < 0)
- return sysfs_emit_at(buf, offset, "-0.%09u", abs(tmp1));
- else
- return sysfs_emit_at(buf, offset, "%d.%09u", tmp0,
- abs(tmp1));
+ case IIO_VAL_FRACTIONAL_LOG2: {
+ u64 t1, t2, mult;
+ int integer, precision;
+ bool neg = vals[0] < 0;
+
+ if (vals[0] > ULLONG_MAX / PICO) {
+ mult = NANO;
+ precision = 9;
+ } else {
+ mult = PICO;
+ precision = 12;
+ }
+ t1 = shift_right((u64)abs(vals[0]) * mult, vals[1]);
+ integer = (int)div64_u64_rem(t1, mult, &t2);
+ if (integer == 0 && neg)
+ return sysfs_emit_at(buf, offset, "-0.%0*llu",
+ precision, abs(t2));
+ if (neg)
+ integer *= -1;
+ return sysfs_emit_at(buf, offset, "%d.%0*llu", integer,
+ precision, abs(t2));
+ }
case IIO_VAL_INT_MULTIPLE:
{
int i;