Хотя @fhdhsni дал вам отличный ответ, если вы беспокоитесь о читабельности, я бы предложил абстрагировать все это в отдельную функцию, например так:
defmodule T do
def parsefloats(stringtobeparsed) do
stringtobeparsed
|> String.replace("[", "")
|> String.replace(",", "")
|> String.replace("]", "")
|> String.split(" ")
|> Enum.map(fn x -> String.to_float(x) end)
end
end
Затем вы называете это так: [113 ]
[x,y] = T.parsefloats("[40.45694301152436, -3.6907402812214514]")
# [40.45694301152436, -3.6907402812214514]
iex(3)> x
# 40.45694301152436
iex(4)> y
# -3.6907402812214514
Не лучше с точки зрения более компактного кода, но, я думаю, более читабельного.
Здесь Вы идете:
// A signed fixed-point 16:16 class
class FixedPoint_16_16
{
short intPart;
unsigned short fracPart;
public:
FixedPoint_16_16(double d)
{
*this = d; // calls operator=
}
FixedPoint_16_16& operator=(double d)
{
intPart = static_cast<short>(d);
fracPart = static_cast<unsigned short>
(numeric_limits<unsigned short> + 1.0)*d);
return *this;
}
// Other operators can be defined here
};
РЕДАКТИРОВАНИЕ: Вот более общий класс на основе anothercommon способа иметь дело с числами фиксированной точки (и на который KPexEA указал):
template <class BaseType, size_t FracDigits>
class fixed_point
{
const static BaseType factor = 1 << FracDigits;
BaseType data;
public:
fixed_point(double d)
{
*this = d; // calls operator=
}
fixed_point& operator=(double d)
{
data = static_cast<BaseType>(d*factor);
return *this;
}
BaseType raw_data() const
{
return data;
}
// Other operators can be defined here
};
fixed_point<int, 8> fp1; // Will be signed 24:8 (if int is 32-bits)
fixed_point<unsigned int, 16> fp1; // Will be unsigned 16:16 (if int is 32-bits)
Состав исполнителей от плавания до целого числа выбросит дробную часть поэтому, если Вы захотите иметь в наличии ту часть как фиксированную точку тогда, Вы просто умножаете плавание прежде, чем бросить его. Ниже кода не проверит на ум переполнения Вас.
, Если Вы хотите 16:16
double f = 1.2345;
int n;
n=(int)(f*65536);
, если Вы хотите 24:8
double f = 1.2345;
int n;
n=(int)(f*256);
Редактирование **** **: Мой первый комментарий относится перед редактированием Kevin, но я оставлю его здесь для потомства. Ответы изменяются так быстро здесь иногда!
проблема с подходом Kevin состоит в том, что с Фиксированной точкой Вы обычно упаковываете в гарантируемый размер слова (обычно 32 бита). Объявление этих двух частей отдельно оставляет Вас прихоти упаковки структуры Вашего компилятора. Да Вы могли вызвать его, но это ни на что не работает кроме 16:16 представления.
KPexEA ближе к метке путем упаковки всего в интервал - хотя я использовал бы "подписываемый долго" для попытки быть явным на 32 битах. Тогда можно использовать его подход для генерации значения фиксированной точки, и разрядное разрезание действительно извлекает составные части снова. Его предложение также покрывает 24:8 случай.
(И все остальные, кто предложил просто static_cast....., что Вы думали?;))
Я дал ответ парню, который записал лучший ответ, но я действительно использовал связанный код вопросов, который указывает здесь .
Это использовало шаблоны и было легко угробить зависимости от lib повышения.
Это хорошо для преобразования от плавающей точки до целого числа, но O.P. также хотел фиксированная точка .
Теперь, как Вы сделали бы это в C++, я не знаю (C++, не являющийся чем-то, в чем я могу думать с готовностью). Возможно, попробуйте масштабировано-целочисленный подход, т.е. используйте целое число на 32 или 64 бита и программно выделите последнее, скажем, 6 цифр к тому, что имеет на правой стороне десятичную точку.
Нет никого созданного в поддержке в C++ для чисел фиксированной точки. Ваш лучший выбор состоял бы в том, чтобы записать обертке класс 'FixedInt', который берет, удваивает и преобразовывает их.
Что касается общего метода преобразовать... международную часть достаточно легко, просто захватите целую часть значения и сохраните ее в верхних битах..., десятичная часть была бы чем-то вроде:
for (int i = 1; i <= precision; i++)
{
if (decimal_part > 1.f/(float)(i + 1)
{
decimal_part -= 1.f/(float)(i + 1);
fixint_value |= (1 << precision - i);
}
}
, хотя это, вероятно, будет содержать ошибки все еще