Страницы

Поиск по вопросам

четверг, 14 февраля 2019 г.

Преобразование прямого кода в десятичный

Подскажите, пожалуйста, как правильно преобразовать прямой код в десятичный?
Прямой код лежит в векторе:
std::vector code;
Содержимое вектора: 0x90 0xa8 0x02. При этом code[0] - десятичная часть, а в code[2] и code[1] целая. Причем старший бит в code[2] обозначает знак числа.
Я реализовал так:
// calculate int8_t pm = 1; if (result[2] & 1<<7){ pm=-1; result[2] ^= 1<<7; } y = (result[2]*256 + result[1] + result[0]/256.0) * pm;
Результат правильный. Но как-то длинно и, мне кажется, неэффективно.


Ответ

Конечно, можно поиздеваться и сделать так:
double dres(const vector&result) { struct Data { unsigned long i: 23; int sign : 1; }; Data *d = (Data*)&result[0]; return double(d->i)/256 *(d->sign ? -1 : 1); }
Ну, принцип вы поняли?
У вас мне очень не нравится то, что вы меняете result[2]
result[2] ^= 1<<7;

среда, 13 февраля 2019 г.

Как правильно прописать отправку сообщения клиенту с сервера?

С помощью vert.x core 3.2.1 написал простенький сервер, который принимает сообщения от подключившегося пользователя, однако хотелось бы реализовать ответ сервера(возврат сообщений пользователя обратно).
Сам код:
import io.vertx.core.Handler; import io.vertx.core.Vertx; import io.vertx.core.buffer.Buffer; import io.vertx.core.http.*;
public class serverTest {
public static void main(String[] args) throws Exception {
HttpServer server = Vertx.vertx().createHttpServer(); server.websocketHandler(new Handler() { @Override public void handle(ServerWebSocket webs) { System.out.println("Client connected"); System.out.println("Client's message: "); webs.handler(new Handler() { @Override public void handle(Buffer event) { System.out.println("Received data " + event.toString("ISO-8859-1")); } }); } }); server.listen(8080, "localhost", res -> { if (res.succeeded()) { System.out.println("Server is now listening!"); } else { System.out.println("Failed to bind!"); } }); } }
Через этот интерфейс и метод handle происходит прием сообщений:
@Override public void handle(Buffer event) { System.out.println("Received data " + event.toString("ISO-8859-1")); }
Как я понимаю, нужно туда вкрутить отправщика и поставить какое-то условия, чтобы в случае если сообщение пришло, он высылал его в ответ. Однако я не совсем понимаю как это сделать=(


Ответ

Поковырявшись и потыкав,обнаружил простой метод, благодаря которому можно слать ответы с сервера. Таким образом, метод handle перепишется следующим образом:
public void handle(Buffer event) { System.out.println("Received data: " + event.toString("ISO-8859-1")); webs.writeFinalTextFrame("echo:"+event.toString("ISO-8859-1"));

Создание кнопки на панели в Хром

Подскажите как создать кнопку на панели в хроме? Она должна по клику открывать ссылку в новой вкладке.

Открыть в новой вкладке


Ответ

Чтобы все было ясно, приведу небольшой работающий пример, который помогает реализовать задачу указанную в вопросе.
Создание расширения процесс достаточно простой и понятный. Разумеется для создания сложных расширений требуется более серьезное знание JavaScript.
И так, наше расширение должно уметь открывать в новой вкладке страницу по нажатии на иконку.
Для начала создаем манифест файл, который содержит в себе все необходимые данные о расширении. Файл должен называться manifest.json. Вот его содерживое.
{ "name": "HTML5", "version": "1", "manifest_version": 2, "icons": { "128": "128.png" }, "browser_action": { "default_title": "Нажмите на иконку HTML5", "default_icon" : "128.png" }, "permissions": ["tabs"], "background":{ "scripts": ["background.js"] } }
name - название нашего расширения для Google Chrome. Под этим именен он будет показываться в списке расширений.
version - версия расширения. Указывается на усмотрение разработчика, но в соотвествии с определенными общепринятыми правилами. Об этом можно отдельно почитать тут
manifest_version - версия нашего манифеста. Это значение фиксированное и его менять не надо.
icons - главная иконка нашего расширения размером 128 на 128. Формат файла - png
browser_action - координирует взаимодействие работы с браузером.
default_title - текст, всплывающий при наведении курсора на иконку.
default_icon - иконка для панели расширений (собственно на нее мы будем нажимать чтобы перейти по ссылке)
permissions - указываем действия, на которые наше расширение должно получить доступ. В нашему случае это возможность работать с ТАБ-ами.
background - указываем данные для фоновой страницы. Какие страницы, скрипты итд загружать в фоновом режиме. Мы лишь указываем на файл background.js.
При нажатии на иконку расширения, в фоновом режиме запустится и исполнится код, который лежит в background.js
Содержание файла background.js:
chrome.browserAction.onClicked.addListener(function(activeTab){
chrome.tabs.create({ url: "https://www.w3.org/html/logo/" }); });
Создаем папку и копируем в нее все три файла: manifest.json, background.js, 128.png

Далее переходим в Google Chrome во вкладку Расширения (Extensions) и нажимаем на кнопку "Загрузить распакованное расширение" (Load unpacked extension). Указываем на нашу папку (которая содержит три файла) и расширение будет установлено.

Иконка появится там где ее ждут :-). Кликаем и переходим на нужный адрес.

Невожможно выбрать модификатор доступа класса

Здравствуйте, столкнулся с проблемой следующего рода: есть public класс. При попытке создать наследника с модификатором отличным от public пишет
"modifier ... not allowed here".
Почитал в интернете нашел, что класс наследник может иметь уровень доступа такой же или "шире" чем родителя. При создании третего класса, который не являеться чьим-либо наследником, пишет
"modifier ... not allowed here"
при private. При модификаторе public понятно (в одном java - файле может быть только один private), protected мне не нужен - наследников не будет. Все классы находятся в одном пекедже и одном файле (программа ведь учебная и небольшая). Проблемы нету только с package модификатором.
Объясните, пожалуйста, что не так.
package Animals;
public class Bird {
public static void main(String[] args) { } }
class Parrot extends Bird { }
private class Cat { }


Ответ

Смотрите. В таком виде private или protected классы Parrot и Cat были бы недоступны никому, даже методу main в классе Bird
Без указания конкретного модификатора классы будут иметь package-видимость, то есть видимы для всех в пределах пакета Animals (кстати, пакеты именуют с маленькой буквы).
Для внутренних (inner) классов задание видимости уже имеет смысл: они могут являться деталями реализации внешнего класса, о которых не нужно знать окружающему миру. Т.е. такой код скомпилируется:
public class Bird { private class Cat { }
public static void main(String[] args) { } }
Этот прием достаточно широко используется в классах, входящих в JDK. Например, список LinkedList не показывает наружу деталь реализации - класс узла списка LinkedList.Node, поэтому объявляет его так:
public class LinkedList extends AbstractSequentialList implements List, Deque, Cloneable, java.io.Serializable { private static class Node { ... } }

Как отправить HTTP запрос из Android-приложения?

Что не так с этим кодом?
import java.io.*; import java.net.*;
...
URL url = new URL(e.getText().toString()); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream());
Если закомментировать последнюю строку, то ничего не происходит. Если же её оставить, то приложение компилируется, но во время выполнения выскакивает сообщение
В приложении "ХХХ" произошла ошибка
и оно аварийно закрывается.


Ответ

Запрос отправляется при вызове getInputStream();
Скорее всего, ошибка, которую вы видите говорит вам о том, что вы делаете HTTP запрос в главном потоке Android приложения (если это не так, дополните вопрос).
Интернет запросам свойственно занимать много времени, а главный поток предназначен прежде всего для обработки и отображения пользовательского интерфейса, который должен реагировать на действия пользователя быстро. Поэтому, необходимо создать новый поток:
Thread t = new Thread(new Runnable(){ public void run(){ //Ваш код для запроса } }).start();
Или, вы можете использовать AsyncTask. Подробнее о нем и вообще о потоках тут: https://habrahabr.ru/post/124484/
Учтите, что Вы не сможете ничего делать с элементами интерфейса не из главного потока. Для того, чтобы выполнить код в главном потоке, используйте Activity.runOnUiThread

Инициализация статического члена в main

Как инициализировать неконстантный статический член класса до создания экземпляра класса в функции main?
Например:
class A { protected: static int x; A(){} public: }; class B: public A { };
int main() { // нужно инициализировать x здесь B b; }


Ответ

Добавьте статическую функцию, которая будет присваивать значение x и вызывайте её:
class A { protected: static int _x; A() {} public: static void InitX(int x) { _x = x; } };
В main
int main() { A::InitX(5); B b; }
Если нужна именно инициализация, то Вы не можете контролировать то, когда она будет выполнена, но она обязательно будет выполнена до main.
В Вашем коде, кстати, как раз не хватает инициализации, а без неё код не соберётся. Добавьте в глобальной области видимости следующее:
int A::x = 0;

Как повернуть группу точек в 2D относительно произвольной точки?

Попробовал сделать по формулам :
И так как поворачивать нужно относительно произвольной точки, то от x и y предварительно отнимается расстояние этой точки от начала координат, а затем добавляется. Вот код(С++) :
void rotate(int &x, int &y, const double &cosVal, const double &sinVal, const int &cx = 0, const int &cy = 0) { const double _x = x - cx; const double _y = y - cy; x = round( _x * cosVal - _y * sinVal); y = round( _x * sinVal + _y * cosVal); x += cx; y += cy; }
Но получается вот это (точка относительно которой крутится - центр треугольника) :
(гифка записана с момента когда треугольник уже начал деформироваться и "уезжать" от своего центра).


Ответ

Вы работаете с математикой с плавающей точкой, при этом используя переменные типа int! Естественно, [накапливающиеся] ошибки округления дают совершенно нелепые результаты!
Используйте для координат переменные типа double, а в int их переводите только для вывода графики (и то можно неявно...)
void rotate(int &x, int &y, const double &cosVal, const double &sinVal, const int &cx = 0, const int &cy = 0)
должна превратиться в
void rotate(double &x, double &y, double cosVal, double sinVal, double cx = 0.0, double cy = 0.0)