Convert a double array to unsigned short?

a 夏天 提交于 2019-12-13 08:57:13

问题


  Prob = *((unsigned short*)(Prob));

  Prob = (unsigned short)(Prob);

This didn't work for me. How to convert it correctly?


回答1:


The biggest issue you face is for those double values that exceed USHRT_MAX. Secondarily, you need to address rounding. A simple approach that addresses both and sets rounding at .5 could look something like the following where the function array_dbl2short returns the number of double values successfully converted to unsigned short:

size_t array_dbl2short (unsigned short *usa, double *da, size_t n)
{
    if (!usa || !da || !n) return 0;
    register size_t i, ncnvt = 0;

    for (i = 0; i < n; i++) {
        if (da[i] < 0 || (unsigned long long)(da[i] + 0.5) > USHRT_MAX)
            fprintf (stderr, "error: %lf outside range for conversion.\n",
                    da[i]);
        else
            usa[ncnvt++] = (unsigned short)(da[i] + 0.5);
    }

    return ncnvt;
}

A short example of its use would be:

#include <stdio.h>
#include <limits.h>

size_t array_dbl2short (unsigned short *usa, double *da, size_t n);

int main (void) {

    double arr[] = { 1.49, 1.5, 65535.49, 65535.5, -1.9, 25671.8 };
    size_t i, n, nelem = sizeof arr/sizeof *arr;
    unsigned short usarr[nelem];

    if ((n = array_dbl2short (usarr, arr, nelem))) {
        printf ("\n unsigned short array:\n\n");
        for (i = 0; i < n; i++)
            printf ("  usarr[%zu] : %hu\n", i, usarr[i]);
    }

    return 0;
}

size_t array_dbl2short (unsigned short *usa, double *da, size_t n)
{
    if (!usa || !da || !n) return 0;
    register size_t i, ncnvt = 0;

    for (i = 0; i < n; i++) {
        if (da[i] < 0 || (unsigned long long)(da[i] + 0.5) > USHRT_MAX)
            fprintf (stderr, "error: %lf outside range for conversion.\n",
                    da[i]);
        else
            usa[ncnvt++] = (unsigned short)(da[i] + 0.5);
    }

    return ncnvt;
}

(note: the real-part of the double values must be capable of being expressed as an unsigned long long for the conversion validations to work properly)

Example Use/Output

$ ./bin/dbl2ushort
error: 65535.500000 outside range for conversion.
error: -1.900000 outside range for conversion.

 unsigned short array:

  usarr[0] : 1
  usarr[1] : 2
  usarr[2] : 65535
  usarr[3] : 25672

This solution doesn't address all possible rounding and conversion issues. You can also use the function in math.h (e.g. modf, round, etc) to preform the real-part and rounding. Let me know if you have further questions.




回答2:


You need to explicitly convert each value:

unsigned short * doubleToUShort(double * Prob_double, size_t N) {
  unsigned short * Prob = malloc(sizeof(unsigned short) * N);
  size_t i = 0;

  for (i = 0; i < N; i++) {
     Prob[i] = Prob_double[i];
  }

  return Prob;
}

That will round towards zero. If you instead want to round to the nearest you can use #include <math.h> and change that loop to

for (i = 0; i < N; i++) {
  Prob[i] = round(Prob_double[i]);
}


来源:https://stackoverflow.com/questions/38228889/convert-a-double-array-to-unsigned-short

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!