Nano Hash - криптовалюты, майнинг, программирование

Как определить количество десятичных знаков в переменной Single-type в Inno Setup?

Мне нужно рассчитать общий размер всех компонентов в моей установке. Из-за некоторого специального кода я не могу использовать для этого внутреннюю функцию Inno Setup.

Проблема заключалась в том, что компоненты совместно используют множество файлов. Поэтому я определил строку для каждого компонента, содержащую переменные для файлов, которые они используют. Затем я добавляю эти строки в одну строку, и если в этой строке обнаруживается определенная переменная, то размер файла в байтах добавляется к переменной «size» типа Single. В конце «размер» показывает, сколько места необходимо для установки.

На самом деле это работает очень хорошо, но затем я хочу показать размер в ГБ на следующей странице. Но функция FloatToStr добавляет много чисел после десятичной запятой, тогда как мне просто нужно два.

Вот сценарий (проблема возникает в самых последних строках):

function NextButtonClick(CurPageID: Integer): Boolean;
var
  size: Single;

  if (CurPageID = wpSelectDir) then { I have swapped the Components and SelectDir pages }
  begin

  size := 0; { this will contain the size in the end }
  xg := '';  { this is the string which contains the list of files needed by every single component }
  for I := 0 to GetArrayLength(ComponentArray) - 1 do
  if IsComponentSelected(ComponentArray[I].Component) then
  begin
    xg := xg + ComponentArray[I].GCF; 
  end;    
  { here the files are being added to the string, everything's working as intended.. }


  MsgBox(xg, mbInformation, MB_OK); { this is for testing if the string has been created correctly }
  if Pos('gcf1', xg) > 0 then size := size + 1512820736; { here the Pos-function searches for the given string and if it is found it adds the value to "size", ok... }
  if Pos('gcf2', xg) > 0 then size := size + 635711488;
  if Pos('gcf3', xg) > 0 then size := size + 286273536;
size := size / 1024 / 1024 / 1024; { now all sizes have been added and the number is converted to be displayed GB, not bytes }
  { Format('%.2n', [size]); }
  { size := (round(size * 10) / 10); }
  { size := Format('%.2n', [size]); }
  { FloatToStr(size); }
  MsgBox(FloatToStr(size), mbInformation, MB_OK); { Here the size is shown but with several unneeded places after the decimal point (2.267589569092) }
  end;
end;

Как видите, я попробовал несколько вещей, чтобы избавиться от чисел. Проблема в функции FloatToStr в MsgBox, она автоматически складывает все числа. Если я выберу тип Integer для "размера", он по-прежнему показывает это длинное число, но я не могу использовать Integer и IntToStr в MsgBox (что решило бы проблему), потому что обрабатываемые здесь числа слишком велики, и я хочу иметь два десятичных знака. после точки.

Я также попытался поместить функцию Format в MsgBox, но тоже получил ошибку «Несоответствие типов».

FloatToStrF не поддерживается Inno Setup.

Преобразование «размера» с использованием FloatToStr заранее и его усечение также не сработало, потому что компилятор проверяет, какой тип «размер» был объявлен как, и снова настаивает на использовании FloatToStr в MsgBox.

Я понятия не имею, как округлить это число. Может, поможет какой-нибудь другой подход?

Жду ваших ответов!


Ответы:


1

Вы можете использовать функцию Format.

Взгляните на этот пример:

procedure TestClick(Sender: TObject);
var
  Size: Extended;
begin
  Size := 0;
  Size := Size + 1512820736
  Size := Size + 635711488;
  Size := Size + 286273536;
  Size := Size / 1024 / 1024 / 1024; { now all sizes have been added and the number is converted to be displayed GB, not bytes }
  MsgBox(Format('%.2f Gb.', [Size]), mbInformation, MB_OK); 
end;

Я меняю тип данных с Single на Extended, принимаю это как личный выбор.

Или используйте эту функцию как более разумный вариант для добавления правильного размера в зависимости от количества байтов:

const
  KFactor = 1024;

function FormatBytes(const Bytes: Extended): string;
var
  Amount: Extended;
  Idx: Byte;
  Dms: array[1..5] of string;
  FmtStr: string;
begin
  Dms[1] := 'B'; Dms[2] := 'KB'; Dms[3] := 'MB'; Dms[4] := 'GB'; Dms[5] := 'TB';
  Amount := Bytes;
  Idx := 1;
  while Amount > (0.9 * KFactor) do
  begin
    Idx := Idx + 1;
    Amount := Amount / KFactor;
  end;
  if Abs(Amount - Trunc(Amount)) < 0.07 then
    FmtStr := '%.0f %s'
  else
    FmtStr := '%.2f %s';
  Result := Format(FmtStr, [Amount, Dms[Idx]]);
end;

Ответ отредактирован для настройки количества десятичных знаков в случае, если должно отображаться почти точное количество КБ / МБ / ГБ / ТБ.

12.11.2012
  • Вау, спасибо большое! Я неправильно использовал функцию форматирования, но теперь она работает! Но я все еще не понимаю, как работает вторая функция ... Не могли бы вы объяснить это немного, пожалуйста? 12.11.2012
  • @ user1662035 Извините, я думаю, что код говорит сам за себя. Если вы пытаетесь понять, как это работает, вы можете отладить его и запустить пошагово. Поместите контрольную точку (F5) в первую строку, и как только она остановит выполнение установщика, вы можете перейти к шагу (F8), проверяя значения переменных, наведя курсор мыши на ее имя в скрипте. 12.11.2012
  • const KFactor = 1024; Я не заметил, что его не было в комплекте. 13.11.2012
  • Большое спасибо, это работает, и теперь я понимаю, почему это решение лучше. Хорошего дня :) 13.11.2012
  • Эээ, еще вопрос ... Можно ли с помощью этой функции избавиться от нулей в конце? Например, как преобразовать 716,00 МБ в 716 МБ? 18.11.2012
  • Конечно, вы можете, просто измените строку формата в соответствии со своими потребностями! 18.11.2012
  • Извините, я просмотрел некоторые подробные объяснения функции форматирования, но я все еще не знаю, как это сделать ... 18.11.2012
  • @user Например, вы можете сделать строку формата переменной и настроить ее на нужное количество десятичных знаков. Я отредактировал свой вопрос, чтобы улучшить это. 19.11.2012
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..